Skip to content

Commit 11e0998

Browse files
authored
feat: Add support for PHP 8.2 (#212)
## Small Fixes due to PHP8.2 upgrade: - Internal PHP `ZendHashmap` changed the way that we access to the bucket ([commit](php/php-src@90b7bde#diff-dca4782c62f10b418ea7193e4641e688ffd7a9c97869f2b1a3a96e28da5653aaL371)) - Internal PHP `ArrayIterator` doesn't support parent `get_iterator` ([commit](php/php-src@15bbf6f#diff-bc002b59b592b4d44c13d898f9dc3ca60b1b1c8505a51a2a3557dfde51dfeb61L273))
1 parent 6965f4a commit 11e0998

File tree

10 files changed

+83
-34
lines changed

10 files changed

+83
-34
lines changed

.github/actions/zts/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM php:8.1-zts
1+
FROM php:8.2-zts
22

33
WORKDIR /tmp
44

.github/workflows/build.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
strategy:
1616
matrix:
1717
os: [ubuntu-latest, macos-latest, windows-latest]
18-
php: ["8.0", "8.1"]
18+
php: ["8.0", "8.1", "8.2"]
1919
rust: [stable, nightly]
2020
clang: ["14"]
2121
phpts: [ts, nts]
@@ -39,6 +39,7 @@ jobs:
3939
php-version: ${{ matrix.php }}
4040
env:
4141
phpts: ${{ matrix.phpts }}
42+
debug: true
4243
- name: Setup Rust
4344
uses: dtolnay/rust-toolchain@master
4445
with:
@@ -87,17 +88,17 @@ jobs:
8788
- name: Test inline examples
8889
run: cargo test --release --all --all-features
8990
- name: Run rustfmt
90-
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.1'
91+
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.2'
9192
run: cargo fmt --all -- --check
9293
- name: Run clippy
93-
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.1'
94+
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.2'
9495
run: cargo clippy --all -- -D warnings
9596
# Docs
9697
- name: Run rustdoc
97-
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.1'
98+
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.2'
9899
run: cargo rustdoc -- -D warnings
99100
- name: Build with docs stub
100-
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.1'
101+
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.2'
101102
env:
102103
DOCS_RS: ""
103104
run: cargo clean && cargo build

.github/workflows/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
strategy:
1616
matrix:
1717
os: ["ubuntu-latest"]
18-
php: ["8.0"]
18+
php: ["8.2"]
1919
clang: ["14"]
2020
mdbook: ["latest"]
2121
steps:

build.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use bindgen::RustTarget;
1616
use impl_::Provider;
1717

1818
const MIN_PHP_API_VER: u32 = 20200930;
19-
const MAX_PHP_API_VER: u32 = 20210902;
19+
const MAX_PHP_API_VER: u32 = 20220829;
2020

2121
pub trait PHPProvider<'a>: Sized {
2222
/// Create a new PHP provider.
@@ -208,10 +208,18 @@ fn check_php_version(info: &PHPInfo) -> Result<()> {
208208
// should get both the `php81` and `php82` flags.
209209
const PHP_81_API_VER: u32 = 20210902;
210210

211-
if version >= PHP_81_API_VER {
211+
const PHP_82_API_VER: u32 = 20220829;
212+
213+
println!("cargo:rustc-cfg=php80");
214+
215+
if (PHP_81_API_VER..PHP_82_API_VER).contains(&version) {
212216
println!("cargo:rustc-cfg=php81");
213217
}
214218

219+
if version >= PHP_82_API_VER {
220+
println!("cargo:rustc-cfg=php82");
221+
}
222+
215223
Ok(())
216224
}
217225

@@ -233,12 +241,13 @@ fn main() -> Result<()> {
233241
}
234242

235243
println!("cargo:rerun-if-changed=build.rs");
244+
println!("cargo:rerun-if-changed=Cargo.lock");
236245

237246
// docs.rs runners only have PHP 7.4 - use pre-generated bindings
238247
if env::var("DOCS_RS").is_ok() {
239248
println!("cargo:warning=docs.rs detected - using stub bindings");
240249
println!("cargo:rustc-cfg=php_debug");
241-
println!("cargo:rustc-cfg=php81");
250+
println!("cargo:rustc-cfg=php82");
242251
std::fs::copy("docsrs_bindings.rs", out_path)
243252
.expect("failed to copy docs.rs stub bindings to out directory");
244253
return Ok(());

docsrs_bindings.rs

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ pub const ZEND_ACC_USE_GUARDS: u32 = 2048;
5454
pub const ZEND_ACC_CONSTANTS_UPDATED: u32 = 4096;
5555
pub const ZEND_ACC_NO_DYNAMIC_PROPERTIES: u32 = 8192;
5656
pub const ZEND_HAS_STATIC_IN_METHODS: u32 = 16384;
57-
pub const ZEND_ACC_REUSE_GET_ITERATOR: u32 = 65536;
5857
pub const ZEND_ACC_RESOLVED_PARENT: u32 = 131072;
5958
pub const ZEND_ACC_RESOLVED_INTERFACES: u32 = 262144;
6059
pub const ZEND_ACC_UNRESOLVED_VARIANCE: u32 = 524288;
@@ -80,7 +79,7 @@ pub const ZEND_ACC_STRICT_TYPES: u32 = 2147483648;
8079
pub const ZEND_ISEMPTY: u32 = 1;
8180
pub const _ZEND_SEND_MODE_SHIFT: u32 = 25;
8281
pub const _ZEND_IS_VARIADIC_BIT: u32 = 134217728;
83-
pub const ZEND_MODULE_API_NO: u32 = 20210902;
82+
pub const ZEND_MODULE_API_NO: u32 = 20220829;
8483
pub const USING_ZTS: u32 = 0;
8584
pub const MAY_BE_BOOL: u32 = 12;
8685
pub const MAY_BE_ANY: u32 = 1022;
@@ -219,7 +218,7 @@ pub struct _zend_array {
219218
pub gc: zend_refcounted_h,
220219
pub u: _zend_array__bindgen_ty_1,
221220
pub nTableMask: u32,
222-
pub arData: *mut Bucket,
221+
pub __bindgen_anon_1: _zend_array__bindgen_ty_2,
223222
pub nNumUsed: u32,
224223
pub nNumOfElements: u32,
225224
pub nTableSize: u32,
@@ -241,6 +240,13 @@ pub struct _zend_array__bindgen_ty_1__bindgen_ty_1 {
241240
pub nIteratorsCount: zend_uchar,
242241
pub _unused2: zend_uchar,
243242
}
243+
#[repr(C)]
244+
#[derive(Copy, Clone)]
245+
pub union _zend_array__bindgen_ty_2 {
246+
pub arHash: *mut u32,
247+
pub arData: *mut Bucket,
248+
pub arPacked: *mut zval,
249+
}
244250
pub type HashPosition = u32;
245251
#[repr(C)]
246252
#[derive(Debug, Copy, Clone)]
@@ -420,6 +426,15 @@ pub struct _zend_class_iterator_funcs {
420426
pub type zend_class_iterator_funcs = _zend_class_iterator_funcs;
421427
#[repr(C)]
422428
#[derive(Debug, Copy, Clone)]
429+
pub struct _zend_class_arrayaccess_funcs {
430+
pub zf_offsetget: *mut zend_function,
431+
pub zf_offsetexists: *mut zend_function,
432+
pub zf_offsetset: *mut zend_function,
433+
pub zf_offsetunset: *mut zend_function,
434+
}
435+
pub type zend_class_arrayaccess_funcs = _zend_class_arrayaccess_funcs;
436+
#[repr(C)]
437+
#[derive(Debug, Copy, Clone)]
423438
pub struct _zend_serialize_data {
424439
_unused: [u8; 0],
425440
}
@@ -468,6 +483,7 @@ pub struct _zend_class_mutable_data {
468483
pub default_properties_table: *mut zval,
469484
pub constants_table: *mut HashTable,
470485
pub ce_flags: u32,
486+
pub backed_enum_table: *mut HashTable,
471487
}
472488
pub type zend_class_mutable_data = _zend_class_mutable_data;
473489
#[repr(C)]
@@ -510,11 +526,11 @@ pub struct _zend_class_entry {
510526
pub default_static_members_count: ::std::os::raw::c_int,
511527
pub default_properties_table: *mut zval,
512528
pub default_static_members_table: *mut zval,
513-
pub static_members_table__ptr: *mut *mut zval,
529+
pub static_members_table__ptr: *mut zval,
514530
pub function_table: HashTable,
515531
pub properties_info: HashTable,
516532
pub constants_table: HashTable,
517-
pub mutable_data__ptr: *mut *mut zend_class_mutable_data,
533+
pub mutable_data__ptr: *mut zend_class_mutable_data,
518534
pub inheritance_cache: *mut zend_inheritance_cache_entry,
519535
pub properties_info_table: *mut *mut _zend_property_info,
520536
pub constructor: *mut zend_function,
@@ -531,6 +547,7 @@ pub struct _zend_class_entry {
531547
pub __serialize: *mut zend_function,
532548
pub __unserialize: *mut zend_function,
533549
pub iterator_funcs_ptr: *mut zend_class_iterator_funcs,
550+
pub arrayaccess_funcs_ptr: *mut zend_class_arrayaccess_funcs,
534551
pub __bindgen_anon_2: _zend_class_entry__bindgen_ty_2,
535552
pub get_iterator: ::std::option::Option<
536553
unsafe extern "C" fn(
@@ -728,10 +745,10 @@ pub type zend_object_cast_t = ::std::option::Option<
728745
readobj: *mut zend_object,
729746
retval: *mut zval,
730747
type_: ::std::os::raw::c_int,
731-
) -> ::std::os::raw::c_int,
748+
) -> zend_result,
732749
>;
733750
pub type zend_object_count_elements_t = ::std::option::Option<
734-
unsafe extern "C" fn(object: *mut zend_object, count: *mut zend_long) -> ::std::os::raw::c_int,
751+
unsafe extern "C" fn(object: *mut zend_object, count: *mut zend_long) -> zend_result,
735752
>;
736753
pub type zend_object_get_closure_t = ::std::option::Option<
737754
unsafe extern "C" fn(
@@ -740,7 +757,7 @@ pub type zend_object_get_closure_t = ::std::option::Option<
740757
fptr_ptr: *mut *mut zend_function,
741758
obj_ptr: *mut *mut zend_object,
742759
check_only: bool,
743-
) -> ::std::os::raw::c_int,
760+
) -> zend_result,
744761
>;
745762
pub type zend_object_get_gc_t = ::std::option::Option<
746763
unsafe extern "C" fn(
@@ -755,7 +772,7 @@ pub type zend_object_do_operation_t = ::std::option::Option<
755772
result: *mut zval,
756773
op1: *mut zval,
757774
op2: *mut zval,
758-
) -> ::std::os::raw::c_int,
775+
) -> zend_result,
759776
>;
760777
#[repr(C)]
761778
#[derive(Debug, Copy, Clone)]
@@ -903,13 +920,13 @@ pub struct _zend_op_array {
903920
pub required_num_args: u32,
904921
pub arg_info: *mut zend_arg_info,
905922
pub attributes: *mut HashTable,
923+
pub T: u32,
924+
pub run_time_cache__ptr: *mut *mut ::std::os::raw::c_void,
906925
pub cache_size: ::std::os::raw::c_int,
907926
pub last_var: ::std::os::raw::c_int,
908-
pub T: u32,
909927
pub last: u32,
910928
pub opcodes: *mut zend_op,
911-
pub run_time_cache__ptr: *mut *mut *mut ::std::os::raw::c_void,
912-
pub static_variables_ptr__ptr: *mut *mut HashTable,
929+
pub static_variables_ptr__ptr: *mut HashTable,
913930
pub static_variables: *mut HashTable,
914931
pub vars: *mut *mut zend_string,
915932
pub refcount: *mut u32,
@@ -943,6 +960,8 @@ pub struct _zend_internal_function {
943960
pub required_num_args: u32,
944961
pub arg_info: *mut zend_internal_arg_info,
945962
pub attributes: *mut HashTable,
963+
pub T: u32,
964+
pub run_time_cache__ptr: *mut *mut ::std::os::raw::c_void,
946965
pub handler: zif_handler,
947966
pub module: *mut _zend_module_entry,
948967
pub reserved: [*mut ::std::os::raw::c_void; 6usize],
@@ -970,6 +989,8 @@ pub struct _zend_function__bindgen_ty_1 {
970989
pub required_num_args: u32,
971990
pub arg_info: *mut zend_arg_info,
972991
pub attributes: *mut HashTable,
992+
pub T: u32,
993+
pub run_time_cache__ptr: *mut *mut ::std::os::raw::c_void,
973994
}
974995
#[repr(C)]
975996
pub struct _zend_execute_data {
@@ -998,6 +1019,12 @@ extern "C" {
9981019
}
9991020
#[repr(C)]
10001021
#[derive(Debug, Copy, Clone)]
1022+
pub struct zend_atomic_bool_s {
1023+
pub value: u8,
1024+
}
1025+
pub type zend_atomic_bool = zend_atomic_bool_s;
1026+
#[repr(C)]
1027+
#[derive(Debug, Copy, Clone)]
10011028
pub struct _zend_stack {
10021029
pub size: ::std::os::raw::c_int,
10031030
pub top: ::std::os::raw::c_int,
@@ -1073,8 +1100,8 @@ pub struct _zend_executor_globals {
10731100
pub in_autoload: *mut HashTable,
10741101
pub full_tables_cleanup: bool,
10751102
pub no_extensions: bool,
1076-
pub vm_interrupt: bool,
1077-
pub timed_out: bool,
1103+
pub vm_interrupt: zend_atomic_bool,
1104+
pub timed_out: zend_atomic_bool,
10781105
pub hard_timeout: zend_long,
10791106
pub regular_list: HashTable,
10801107
pub persistent_list: HashTable,
@@ -1118,6 +1145,8 @@ pub struct _zend_executor_globals {
11181145
pub record_errors: bool,
11191146
pub num_errors: u32,
11201147
pub errors: *mut *mut zend_error_info,
1148+
pub filename_override: *mut zend_string,
1149+
pub lineno_override: zend_long,
11211150
pub reserved: [*mut ::std::os::raw::c_void; 6usize],
11221151
}
11231152
pub type zend_module_entry = _zend_module_entry;

src/builders/class.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ impl ClassBuilder {
247247
// disable serialization if the class has an associated object
248248
if self.object_override.is_some() {
249249
cfg_if::cfg_if! {
250-
if #[cfg(php81)] {
250+
if #[cfg(any(php81, php82))] {
251251
class.ce_flags |= ClassFlags::NotSerializable.bits();
252252
} else {
253253
class.serialize = Some(crate::ffi::zend_class_serialize_deny);

src/flags.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
33
use bitflags::bitflags;
44

5+
#[cfg(not(php82))]
6+
use crate::ffi::ZEND_ACC_REUSE_GET_ITERATOR;
57
use crate::ffi::{
68
CONST_CS, CONST_DEPRECATED, CONST_NO_FILE_CACHE, CONST_PERSISTENT, IS_ARRAY, IS_CALLABLE,
79
IS_CONSTANT_AST, IS_DOUBLE, IS_FALSE, IS_LONG, IS_MIXED, IS_NULL, IS_OBJECT, IS_PTR,
@@ -14,10 +16,10 @@ use crate::ffi::{
1416
ZEND_ACC_IMPLICIT_ABSTRACT_CLASS, ZEND_ACC_INTERFACE, ZEND_ACC_LINKED, ZEND_ACC_NEARLY_LINKED,
1517
ZEND_ACC_NEVER_CACHE, ZEND_ACC_NO_DYNAMIC_PROPERTIES, ZEND_ACC_PRELOADED, ZEND_ACC_PRIVATE,
1618
ZEND_ACC_PROMOTED, ZEND_ACC_PROTECTED, ZEND_ACC_PUBLIC, ZEND_ACC_RESOLVED_INTERFACES,
17-
ZEND_ACC_RESOLVED_PARENT, ZEND_ACC_RETURN_REFERENCE, ZEND_ACC_REUSE_GET_ITERATOR,
18-
ZEND_ACC_STATIC, ZEND_ACC_STRICT_TYPES, ZEND_ACC_TOP_LEVEL, ZEND_ACC_TRAIT,
19-
ZEND_ACC_TRAIT_CLONE, ZEND_ACC_UNRESOLVED_VARIANCE, ZEND_ACC_USES_THIS, ZEND_ACC_USE_GUARDS,
20-
ZEND_ACC_VARIADIC, ZEND_HAS_STATIC_IN_METHODS, Z_TYPE_FLAGS_SHIFT, _IS_BOOL,
19+
ZEND_ACC_RESOLVED_PARENT, ZEND_ACC_RETURN_REFERENCE, ZEND_ACC_STATIC, ZEND_ACC_STRICT_TYPES,
20+
ZEND_ACC_TOP_LEVEL, ZEND_ACC_TRAIT, ZEND_ACC_TRAIT_CLONE, ZEND_ACC_UNRESOLVED_VARIANCE,
21+
ZEND_ACC_USES_THIS, ZEND_ACC_USE_GUARDS, ZEND_ACC_VARIADIC, ZEND_HAS_STATIC_IN_METHODS,
22+
Z_TYPE_FLAGS_SHIFT, _IS_BOOL,
2123
};
2224

2325
use std::{convert::TryFrom, fmt::Display};
@@ -75,13 +77,14 @@ bitflags! {
7577
const ConstantsUpdated = ZEND_ACC_CONSTANTS_UPDATED;
7678
const NoDynamicProperties = ZEND_ACC_NO_DYNAMIC_PROPERTIES;
7779
const HasStaticInMethods = ZEND_HAS_STATIC_IN_METHODS;
80+
#[cfg(not(php82))]
7881
const ReuseGetIterator = ZEND_ACC_REUSE_GET_ITERATOR;
7982
const ResolvedParent = ZEND_ACC_RESOLVED_PARENT;
8083
const ResolvedInterfaces = ZEND_ACC_RESOLVED_INTERFACES;
8184
const UnresolvedVariance = ZEND_ACC_UNRESOLVED_VARIANCE;
8285
const NearlyLinked = ZEND_ACC_NEARLY_LINKED;
8386

84-
#[cfg(php81)]
87+
#[cfg(any(php81,php82))]
8588
const NotSerializable = crate::ffi::ZEND_ACC_NOT_SERIALIZABLE;
8689
}
8790
}

src/types/array.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,11 +531,18 @@ impl<'a> Iter<'a> {
531531
///
532532
/// * `ht` - The hashtable to iterate.
533533
pub fn new(ht: &'a ZendHashTable) -> Self {
534-
Self {
534+
#[cfg(not(php82))]
535+
return Self {
535536
ht,
536537
pos: NonNull::new(ht.arData),
537538
end: NonNull::new(unsafe { ht.arData.offset(ht.nNumUsed as isize) }),
538-
}
539+
};
540+
#[cfg(php82)]
541+
return Self {
542+
ht,
543+
pos: NonNull::new(unsafe { ht.__bindgen_anon_1.arData }),
544+
end: NonNull::new(unsafe { ht.__bindgen_anon_1.arData.offset(ht.nNumUsed as isize) }),
545+
};
539546
}
540547
}
541548

src/types/string.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ impl ZendStr {
251251
/// assert_eq!(s.len(), 13);
252252
/// ```
253253
pub fn len(&self) -> usize {
254-
self.len as usize
254+
self.len
255255
}
256256

257257
/// Returns true if the string is empty, false otherwise.

src/zend/ex.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ impl ExecuteData {
213213
#[doc(hidden)]
214214
unsafe fn zend_call_var_num(&self, n: isize) -> *mut Zval {
215215
let ptr = self as *const Self as *mut Zval;
216-
ptr.offset(Self::zend_call_frame_slot() + n as isize)
216+
ptr.offset(Self::zend_call_frame_slot() + n)
217217
}
218218

219219
/// Translation of macro `ZEND_CALL_FRAME_SLOT`

0 commit comments

Comments
 (0)