From 3bf0a18aa57996998c650793af9a2503fddfeafd Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Sun, 23 Aug 2026 12:40:47 +0200 Subject: [PATCH 1/5] tests: Check PHP 8.6 --- .github/workflows/integration.yml | 49 +++++++++++++++++-------------- docker-alpine | 1 - 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index cb5b823c..3e1d09cb 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -2,7 +2,7 @@ name: CI on: [push, pull_request] jobs: - Alpine: + alpine: strategy: matrix: php-version: @@ -14,27 +14,27 @@ jobs: - "8.5-cli-alpine3.22" runs-on: ubuntu-latest steps: - - name: "Checkout" - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v7 - - name: "Build and test extension" + - name: Build and test extension run: "docker build -t simdjsontest -f docker-alpine --build-arg BASE_IMAGE=${{ matrix.php-version }} ." - - name: "Show info" + - name: Show info run: "docker run --rm simdjsontest php --ri simdjson" - Ubuntu-dev: + ubuntu-dev: strategy: matrix: php-version: - - "8.2.30" - - "8.3.30" - - "8.4.17" - - "8.5.2" + - "8.2.33" + - "8.3.33" + - "8.4.24" + - "8.5.9" runs-on: ubuntu-latest steps: - - name: "Checkout" - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v7 - name: Install required packages run: | @@ -61,7 +61,7 @@ jobs: NO_INTERACTION: "true" run: make test TESTS="-m --show-diff -j$(nproc)" - Ubuntu: + ubuntu: strategy: fail-fast: false matrix: @@ -72,6 +72,7 @@ jobs: - "8.3" - "8.4" - "8.5" + - "8.6" os: - ubuntu-latest - ubuntu-24.04-arm @@ -81,7 +82,7 @@ jobs: continue-on-error: ${{ matrix.experimental }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Install PHP uses: shivammathur/setup-php@v2 @@ -92,16 +93,19 @@ jobs: tools: pecl, phpize, php-config - name: Build extension - env: - NO_INTERACTION: "true" - SIMDJSON_HIGH_MEMORY_TESTS: "1" run: | php-config --extension-dir phpize ./configure make -j$(nproc) sudo make install - make test TESTS="--show-diff -j2 -q" + + - name: Run tests + env: + NO_INTERACTION: "true" + SIMDJSON_HIGH_MEMORY_TESTS: "1" + run: | + make test TESTS="--show-diff -j2 -q" - name: Show run: "php -dextension=simdjson.so --ri simdjson" @@ -119,7 +123,7 @@ jobs: echo done - Macos: + macos: runs-on: macos-latest continue-on-error: false strategy: @@ -128,7 +132,7 @@ jobs: php: ['8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Install PHP ${{ matrix.php }} uses: shivammathur/setup-php@v2 @@ -138,13 +142,14 @@ jobs: coverage: none tools: none - - name: Build simdjson + - name: Build extension run: | phpize ./configure make -j$(nproc) - name: Run tests + env: + SIMDJSON_HIGH_MEMORY_TESTS: "1" run: | - export SIMDJSON_HIGH_MEMORY_TESTS=1 make test TESTS="--show-diff -j2 -q" diff --git a/docker-alpine b/docker-alpine index 5a45960d..b7502d33 100644 --- a/docker-alpine +++ b/docker-alpine @@ -6,7 +6,6 @@ RUN apk add --no-cache --virtual .build-deps autoconf \ gcc \ make \ pkgconf \ - git \ re2c COPY . /tmp/simdjson From 2ca0cbd808d80a86c6e765e9bbde2a01d05f0b9c Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Sun, 23 Aug 2026 12:46:39 +0200 Subject: [PATCH 2/5] portability: EMPTY_SWITCH_DEFAULT_CASE is removed in PHP 8.6 in favor of ZEND_UNREACHABLE --- src/simdjson_decoder.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/simdjson_decoder.cpp b/src/simdjson_decoder.cpp index d678e40b..f6bd9119 100644 --- a/src/simdjson_decoder.cpp +++ b/src/simdjson_decoder.cpp @@ -523,7 +523,7 @@ static void simdjson_create_array(simdjson_php_parser *parser, simdjson::dom::el } break; } - EMPTY_SWITCH_DEFAULT_CASE(); + ZEND_UNREACHABLE(); } } @@ -596,7 +596,7 @@ static simdjson_php_error_code simdjson_create_object(simdjson_php_parser *parse } break; } - EMPTY_SWITCH_DEFAULT_CASE(); + ZEND_UNREACHABLE(); } return simdjson::SUCCESS; } @@ -654,7 +654,7 @@ static simdjson_php_error_code simdjson_ondemand_validate(simdjson::ondemand::va return element.get_bool().error(); case simdjson::ondemand::json_type::null: return element.is_null().error(); - EMPTY_SWITCH_DEFAULT_CASE(); + ZEND_UNREACHABLE(); } return simdjson::SUCCESS; } From 354b69b95d6c8d195127b68c4f5c95fe888beb90 Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Sun, 23 Aug 2026 13:06:06 +0200 Subject: [PATCH 3/5] portability: Since PHP 8.6, HT_SIZE_* macros was converted to functions # Conflicts: # src/simdjson_decoder_defs.h --- src/simdjson_decoder_defs.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/simdjson_decoder_defs.h b/src/simdjson_decoder_defs.h index 30b81399..00de18d6 100644 --- a/src/simdjson_decoder_defs.h +++ b/src/simdjson_decoder_defs.h @@ -16,6 +16,15 @@ #include "php.h" #include "simdjson.h" +#if PHP_VERSION_ID >= 80600 +// Since PHP 8.6, HT_SIZE_* macros was converted to functions, so we have to compute array size +#define SIMDJSON_DEDUP_DATA_SIZE(nTableSize) \ + ((size_t)nTableSize) * sizeof(Bucket) + ((size_t)(-((uint32_t)(-(nTableSize + nTableSize))))) * sizeof(uint32_t) +#else +#define SIMDJSON_DEDUP_DATA_SIZE(nTableSize) \ + HT_SIZE_EX(nTableSize, HT_SIZE_TO_MASK(nTableSize)) +#endif + bool simdjson_realloc_needed(const zend_string *str); bool simdjson_simple_decode(const char *json, size_t len, zval *return_value, bool associative); @@ -28,7 +37,7 @@ struct simdjson_php_parser { simdjson::ondemand::parser ondemand_parser; HashTable dedup_key_strings; #if PHP_VERSION_ID >= 80200 - char dedup_key_strings_data[HT_SIZE_EX(SIMDJSON_DEDUP_STRING_COUNT, HT_SIZE_TO_MASK(SIMDJSON_DEDUP_STRING_COUNT))]; + char dedup_key_strings_data[SIMDJSON_DEDUP_DATA_SIZE(SIMDJSON_DEDUP_STRING_COUNT)]; #endif }; From 3106ea07c5f299fce9101651cdc0cede94524ff6 Mon Sep 17 00:00:00 2001 From: Jakub Onderka Date: Sun, 23 Aug 2026 13:22:45 +0200 Subject: [PATCH 4/5] portability: Use ZEND_CONTAINER_OF that is defined since PHP 8.6 --- src/simdjson_compatibility.h | 5 +++++ src/simdjson_encoder.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/simdjson_compatibility.h b/src/simdjson_compatibility.h index a6762a23..bd85ed0d 100644 --- a/src/simdjson_compatibility.h +++ b/src/simdjson_compatibility.h @@ -15,6 +15,11 @@ #define ZEND_HASH_PACKED_FOREACH_VAL(table, data) ZEND_HASH_FOREACH_VAL(table, data) #endif +// ZEND_CONTAINER_OF is available since PHP 8.6 +#ifndef ZEND_CONTAINER_OF +#define ZEND_CONTAINER_OF(ptr, Type, member) ((Type*)((char*)(ptr) - XtOffsetOf(Type, member))) +#endif + #ifndef ZEND_FALLTHROUGH /* pseudo fallthrough keyword; */ #if defined(__GNUC__) && __GNUC__ >= 7 diff --git a/src/simdjson_encoder.cpp b/src/simdjson_encoder.cpp index fdc7fcd5..6662b502 100644 --- a/src/simdjson_encoder.cpp +++ b/src/simdjson_encoder.cpp @@ -765,7 +765,7 @@ static zend_result simdjson_encode_spl_fixedarray(smart_str *buf, const zval *va } zend_object *obj = Z_OBJ_P(val); - simdjson_spl_fixedarray_object *intern = (simdjson_spl_fixedarray_object *)((char *)obj - XtOffsetOf(simdjson_spl_fixedarray_object, std)); + simdjson_spl_fixedarray_object *intern = ZEND_CONTAINER_OF(obj, simdjson_spl_fixedarray_object, std); if (intern->array.elements == NULL) { ZEND_ASSERT(intern->array.size == 0); From d79eef8b4c6435d713de903e06d04170aba544d5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 23 Aug 2026 12:00:31 +0000 Subject: [PATCH 5/5] Fix unreachable handling in switch statements Co-authored-by: JakubOnderka <163343+JakubOnderka@users.noreply.github.com> --- src/simdjson_decoder.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/simdjson_decoder.cpp b/src/simdjson_decoder.cpp index f6bd9119..b4f0b58c 100644 --- a/src/simdjson_decoder.cpp +++ b/src/simdjson_decoder.cpp @@ -523,7 +523,8 @@ static void simdjson_create_array(simdjson_php_parser *parser, simdjson::dom::el } break; } - ZEND_UNREACHABLE(); + default: + ZEND_UNREACHABLE(); } } @@ -596,7 +597,8 @@ static simdjson_php_error_code simdjson_create_object(simdjson_php_parser *parse } break; } - ZEND_UNREACHABLE(); + default: + ZEND_UNREACHABLE(); } return simdjson::SUCCESS; } @@ -654,7 +656,8 @@ static simdjson_php_error_code simdjson_ondemand_validate(simdjson::ondemand::va return element.get_bool().error(); case simdjson::ondemand::json_type::null: return element.is_null().error(); - ZEND_UNREACHABLE(); + default: + ZEND_UNREACHABLE(); } return simdjson::SUCCESS; }