Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for PHP 8.2 #212

Merged
merged 5 commits into from
Dec 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/zts/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM php:8.1-zts
FROM php:8.2-zts

WORKDIR /tmp

Expand Down
11 changes: 6 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
php: ["8.0", "8.1"]
php: ["8.0", "8.1", "8.2"]
rust: [stable, nightly]
clang: ["14"]
phpts: [ts, nts]
Expand All @@ -39,6 +39,7 @@ jobs:
php-version: ${{ matrix.php }}
env:
phpts: ${{ matrix.phpts }}
debug: true
- name: Setup Rust
uses: dtolnay/rust-toolchain@master
with:
Expand Down Expand Up @@ -87,17 +88,17 @@ jobs:
- name: Test inline examples
run: cargo test --release --all --all-features
- name: Run rustfmt
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.1'
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.2'
run: cargo fmt --all -- --check
- name: Run clippy
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.1'
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.2'
run: cargo clippy --all -- -D warnings
# Docs
- name: Run rustdoc
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.1'
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.2'
run: cargo rustdoc -- -D warnings
- name: Build with docs stub
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.1'
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && matrix.php == '8.2'
env:
DOCS_RS: ""
run: cargo clean && cargo build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
matrix:
os: ["ubuntu-latest"]
php: ["8.0"]
php: ["8.2"]
clang: ["14"]
mdbook: ["latest"]
steps:
Expand Down
15 changes: 12 additions & 3 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use bindgen::RustTarget;
use impl_::Provider;

const MIN_PHP_API_VER: u32 = 20200930;
const MAX_PHP_API_VER: u32 = 20210902;
const MAX_PHP_API_VER: u32 = 20220829;

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

if version >= PHP_81_API_VER {
const PHP_82_API_VER: u32 = 20220829;

println!("cargo:rustc-cfg=php80");

if (PHP_81_API_VER..PHP_82_API_VER).contains(&version) {
println!("cargo:rustc-cfg=php81");
}

if version >= PHP_82_API_VER {
println!("cargo:rustc-cfg=php82");
}

Ok(())
}

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

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

// docs.rs runners only have PHP 7.4 - use pre-generated bindings
if env::var("DOCS_RS").is_ok() {
println!("cargo:warning=docs.rs detected - using stub bindings");
println!("cargo:rustc-cfg=php_debug");
println!("cargo:rustc-cfg=php81");
println!("cargo:rustc-cfg=php82");
std::fs::copy("docsrs_bindings.rs", out_path)
.expect("failed to copy docs.rs stub bindings to out directory");
return Ok(());
Expand Down
57 changes: 43 additions & 14 deletions docsrs_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ pub const ZEND_ACC_USE_GUARDS: u32 = 2048;
pub const ZEND_ACC_CONSTANTS_UPDATED: u32 = 4096;
pub const ZEND_ACC_NO_DYNAMIC_PROPERTIES: u32 = 8192;
pub const ZEND_HAS_STATIC_IN_METHODS: u32 = 16384;
pub const ZEND_ACC_REUSE_GET_ITERATOR: u32 = 65536;
pub const ZEND_ACC_RESOLVED_PARENT: u32 = 131072;
pub const ZEND_ACC_RESOLVED_INTERFACES: u32 = 262144;
pub const ZEND_ACC_UNRESOLVED_VARIANCE: u32 = 524288;
Expand All @@ -80,7 +79,7 @@ pub const ZEND_ACC_STRICT_TYPES: u32 = 2147483648;
pub const ZEND_ISEMPTY: u32 = 1;
pub const _ZEND_SEND_MODE_SHIFT: u32 = 25;
pub const _ZEND_IS_VARIADIC_BIT: u32 = 134217728;
pub const ZEND_MODULE_API_NO: u32 = 20210902;
pub const ZEND_MODULE_API_NO: u32 = 20220829;
pub const USING_ZTS: u32 = 0;
pub const MAY_BE_BOOL: u32 = 12;
pub const MAY_BE_ANY: u32 = 1022;
Expand Down Expand Up @@ -219,7 +218,7 @@ pub struct _zend_array {
pub gc: zend_refcounted_h,
pub u: _zend_array__bindgen_ty_1,
pub nTableMask: u32,
pub arData: *mut Bucket,
pub __bindgen_anon_1: _zend_array__bindgen_ty_2,
pub nNumUsed: u32,
pub nNumOfElements: u32,
pub nTableSize: u32,
Expand All @@ -241,6 +240,13 @@ pub struct _zend_array__bindgen_ty_1__bindgen_ty_1 {
pub nIteratorsCount: zend_uchar,
pub _unused2: zend_uchar,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union _zend_array__bindgen_ty_2 {
pub arHash: *mut u32,
pub arData: *mut Bucket,
pub arPacked: *mut zval,
}
pub type HashPosition = u32;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -420,6 +426,15 @@ pub struct _zend_class_iterator_funcs {
pub type zend_class_iterator_funcs = _zend_class_iterator_funcs;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _zend_class_arrayaccess_funcs {
pub zf_offsetget: *mut zend_function,
pub zf_offsetexists: *mut zend_function,
pub zf_offsetset: *mut zend_function,
pub zf_offsetunset: *mut zend_function,
}
pub type zend_class_arrayaccess_funcs = _zend_class_arrayaccess_funcs;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _zend_serialize_data {
_unused: [u8; 0],
}
Expand Down Expand Up @@ -468,6 +483,7 @@ pub struct _zend_class_mutable_data {
pub default_properties_table: *mut zval,
pub constants_table: *mut HashTable,
pub ce_flags: u32,
pub backed_enum_table: *mut HashTable,
}
pub type zend_class_mutable_data = _zend_class_mutable_data;
#[repr(C)]
Expand Down Expand Up @@ -510,11 +526,11 @@ pub struct _zend_class_entry {
pub default_static_members_count: ::std::os::raw::c_int,
pub default_properties_table: *mut zval,
pub default_static_members_table: *mut zval,
pub static_members_table__ptr: *mut *mut zval,
pub static_members_table__ptr: *mut zval,
pub function_table: HashTable,
pub properties_info: HashTable,
pub constants_table: HashTable,
pub mutable_data__ptr: *mut *mut zend_class_mutable_data,
pub mutable_data__ptr: *mut zend_class_mutable_data,
pub inheritance_cache: *mut zend_inheritance_cache_entry,
pub properties_info_table: *mut *mut _zend_property_info,
pub constructor: *mut zend_function,
Expand All @@ -531,6 +547,7 @@ pub struct _zend_class_entry {
pub __serialize: *mut zend_function,
pub __unserialize: *mut zend_function,
pub iterator_funcs_ptr: *mut zend_class_iterator_funcs,
pub arrayaccess_funcs_ptr: *mut zend_class_arrayaccess_funcs,
pub __bindgen_anon_2: _zend_class_entry__bindgen_ty_2,
pub get_iterator: ::std::option::Option<
unsafe extern "C" fn(
Expand Down Expand Up @@ -728,10 +745,10 @@ pub type zend_object_cast_t = ::std::option::Option<
readobj: *mut zend_object,
retval: *mut zval,
type_: ::std::os::raw::c_int,
) -> ::std::os::raw::c_int,
) -> zend_result,
>;
pub type zend_object_count_elements_t = ::std::option::Option<
unsafe extern "C" fn(object: *mut zend_object, count: *mut zend_long) -> ::std::os::raw::c_int,
unsafe extern "C" fn(object: *mut zend_object, count: *mut zend_long) -> zend_result,
>;
pub type zend_object_get_closure_t = ::std::option::Option<
unsafe extern "C" fn(
Expand All @@ -740,7 +757,7 @@ pub type zend_object_get_closure_t = ::std::option::Option<
fptr_ptr: *mut *mut zend_function,
obj_ptr: *mut *mut zend_object,
check_only: bool,
) -> ::std::os::raw::c_int,
) -> zend_result,
>;
pub type zend_object_get_gc_t = ::std::option::Option<
unsafe extern "C" fn(
Expand All @@ -755,7 +772,7 @@ pub type zend_object_do_operation_t = ::std::option::Option<
result: *mut zval,
op1: *mut zval,
op2: *mut zval,
) -> ::std::os::raw::c_int,
) -> zend_result,
>;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -903,13 +920,13 @@ pub struct _zend_op_array {
pub required_num_args: u32,
pub arg_info: *mut zend_arg_info,
pub attributes: *mut HashTable,
pub T: u32,
pub run_time_cache__ptr: *mut *mut ::std::os::raw::c_void,
pub cache_size: ::std::os::raw::c_int,
pub last_var: ::std::os::raw::c_int,
pub T: u32,
pub last: u32,
pub opcodes: *mut zend_op,
pub run_time_cache__ptr: *mut *mut *mut ::std::os::raw::c_void,
pub static_variables_ptr__ptr: *mut *mut HashTable,
pub static_variables_ptr__ptr: *mut HashTable,
pub static_variables: *mut HashTable,
pub vars: *mut *mut zend_string,
pub refcount: *mut u32,
Expand Down Expand Up @@ -943,6 +960,8 @@ pub struct _zend_internal_function {
pub required_num_args: u32,
pub arg_info: *mut zend_internal_arg_info,
pub attributes: *mut HashTable,
pub T: u32,
pub run_time_cache__ptr: *mut *mut ::std::os::raw::c_void,
pub handler: zif_handler,
pub module: *mut _zend_module_entry,
pub reserved: [*mut ::std::os::raw::c_void; 6usize],
Expand Down Expand Up @@ -970,6 +989,8 @@ pub struct _zend_function__bindgen_ty_1 {
pub required_num_args: u32,
pub arg_info: *mut zend_arg_info,
pub attributes: *mut HashTable,
pub T: u32,
pub run_time_cache__ptr: *mut *mut ::std::os::raw::c_void,
}
#[repr(C)]
pub struct _zend_execute_data {
Expand Down Expand Up @@ -998,6 +1019,12 @@ extern "C" {
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct zend_atomic_bool_s {
pub value: u8,
}
pub type zend_atomic_bool = zend_atomic_bool_s;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _zend_stack {
pub size: ::std::os::raw::c_int,
pub top: ::std::os::raw::c_int,
Expand Down Expand Up @@ -1073,8 +1100,8 @@ pub struct _zend_executor_globals {
pub in_autoload: *mut HashTable,
pub full_tables_cleanup: bool,
pub no_extensions: bool,
pub vm_interrupt: bool,
pub timed_out: bool,
pub vm_interrupt: zend_atomic_bool,
pub timed_out: zend_atomic_bool,
pub hard_timeout: zend_long,
pub regular_list: HashTable,
pub persistent_list: HashTable,
Expand Down Expand Up @@ -1118,6 +1145,8 @@ pub struct _zend_executor_globals {
pub record_errors: bool,
pub num_errors: u32,
pub errors: *mut *mut zend_error_info,
pub filename_override: *mut zend_string,
pub lineno_override: zend_long,
pub reserved: [*mut ::std::os::raw::c_void; 6usize],
}
pub type zend_module_entry = _zend_module_entry;
Expand Down
2 changes: 1 addition & 1 deletion src/builders/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ impl ClassBuilder {
// disable serialization if the class has an associated object
if self.object_override.is_some() {
cfg_if::cfg_if! {
if #[cfg(php81)] {
if #[cfg(any(php81, php82))] {
class.ce_flags |= ClassFlags::NotSerializable.bits();
} else {
class.serialize = Some(crate::ffi::zend_class_serialize_deny);
Expand Down
13 changes: 8 additions & 5 deletions src/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

use bitflags::bitflags;

#[cfg(not(php82))]
use crate::ffi::ZEND_ACC_REUSE_GET_ITERATOR;
use crate::ffi::{
CONST_CS, CONST_DEPRECATED, CONST_NO_FILE_CACHE, CONST_PERSISTENT, IS_ARRAY, IS_CALLABLE,
IS_CONSTANT_AST, IS_DOUBLE, IS_FALSE, IS_LONG, IS_MIXED, IS_NULL, IS_OBJECT, IS_PTR,
Expand All @@ -14,10 +16,10 @@ use crate::ffi::{
ZEND_ACC_IMPLICIT_ABSTRACT_CLASS, ZEND_ACC_INTERFACE, ZEND_ACC_LINKED, ZEND_ACC_NEARLY_LINKED,
ZEND_ACC_NEVER_CACHE, ZEND_ACC_NO_DYNAMIC_PROPERTIES, ZEND_ACC_PRELOADED, ZEND_ACC_PRIVATE,
ZEND_ACC_PROMOTED, ZEND_ACC_PROTECTED, ZEND_ACC_PUBLIC, ZEND_ACC_RESOLVED_INTERFACES,
ZEND_ACC_RESOLVED_PARENT, ZEND_ACC_RETURN_REFERENCE, ZEND_ACC_REUSE_GET_ITERATOR,
ZEND_ACC_STATIC, ZEND_ACC_STRICT_TYPES, ZEND_ACC_TOP_LEVEL, ZEND_ACC_TRAIT,
ZEND_ACC_TRAIT_CLONE, ZEND_ACC_UNRESOLVED_VARIANCE, ZEND_ACC_USES_THIS, ZEND_ACC_USE_GUARDS,
ZEND_ACC_VARIADIC, ZEND_HAS_STATIC_IN_METHODS, Z_TYPE_FLAGS_SHIFT, _IS_BOOL,
ZEND_ACC_RESOLVED_PARENT, ZEND_ACC_RETURN_REFERENCE, ZEND_ACC_STATIC, ZEND_ACC_STRICT_TYPES,
ZEND_ACC_TOP_LEVEL, ZEND_ACC_TRAIT, ZEND_ACC_TRAIT_CLONE, ZEND_ACC_UNRESOLVED_VARIANCE,
ZEND_ACC_USES_THIS, ZEND_ACC_USE_GUARDS, ZEND_ACC_VARIADIC, ZEND_HAS_STATIC_IN_METHODS,
Z_TYPE_FLAGS_SHIFT, _IS_BOOL,
};

use std::{convert::TryFrom, fmt::Display};
Expand Down Expand Up @@ -75,13 +77,14 @@ bitflags! {
const ConstantsUpdated = ZEND_ACC_CONSTANTS_UPDATED;
const NoDynamicProperties = ZEND_ACC_NO_DYNAMIC_PROPERTIES;
const HasStaticInMethods = ZEND_HAS_STATIC_IN_METHODS;
#[cfg(not(php82))]
const ReuseGetIterator = ZEND_ACC_REUSE_GET_ITERATOR;
const ResolvedParent = ZEND_ACC_RESOLVED_PARENT;
const ResolvedInterfaces = ZEND_ACC_RESOLVED_INTERFACES;
const UnresolvedVariance = ZEND_ACC_UNRESOLVED_VARIANCE;
const NearlyLinked = ZEND_ACC_NEARLY_LINKED;

#[cfg(php81)]
#[cfg(any(php81,php82))]
const NotSerializable = crate::ffi::ZEND_ACC_NOT_SERIALIZABLE;
}
}
Expand Down
11 changes: 9 additions & 2 deletions src/types/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,11 +531,18 @@ impl<'a> Iter<'a> {
///
/// * `ht` - The hashtable to iterate.
pub fn new(ht: &'a ZendHashTable) -> Self {
Self {
#[cfg(not(php82))]
return Self {
ht,
pos: NonNull::new(ht.arData),
end: NonNull::new(unsafe { ht.arData.offset(ht.nNumUsed as isize) }),
}
};
#[cfg(php82)]
return Self {
ht,
pos: NonNull::new(unsafe { ht.__bindgen_anon_1.arData }),
end: NonNull::new(unsafe { ht.__bindgen_anon_1.arData.offset(ht.nNumUsed as isize) }),
};
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/types/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ impl ZendStr {
/// assert_eq!(s.len(), 13);
/// ```
pub fn len(&self) -> usize {
self.len as usize
self.len
}

/// Returns true if the string is empty, false otherwise.
Expand Down
2 changes: 1 addition & 1 deletion src/zend/ex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ impl ExecuteData {
#[doc(hidden)]
unsafe fn zend_call_var_num(&self, n: isize) -> *mut Zval {
let ptr = self as *const Self as *mut Zval;
ptr.offset(Self::zend_call_frame_slot() + n as isize)
ptr.offset(Self::zend_call_frame_slot() + n)
}

/// Translation of macro `ZEND_CALL_FRAME_SLOT`
Expand Down