Add support for SapiGlobals

This commit is contained in:
Joe Hoyle 2023-07-12 20:05:37 +02:00
parent 36d6159514
commit ca04318cf8
5 changed files with 161 additions and 140 deletions

View File

@ -226,6 +226,8 @@ bind! {
executor_globals,
php_core_globals,
core_globals,
sapi_globals_struct,
sapi_globals,
php_printf,
__zend_malloc,
tsrm_get_ls_cache,

View File

@ -1,7 +1,7 @@
/* automatically generated by rust-bindgen 0.65.1 */
pub const ZEND_DEBUG: u32 = 1;
pub const _ZEND_TYPE_NAME_BIT: u32 = 16777216;
pub const ZEND_DEBUG: u32 = 0;
pub const _ZEND_TYPE_NAME_BIT: u32 = 8388608;
pub const _ZEND_TYPE_NULLABLE_BIT: u32 = 2;
pub const HT_MIN_SIZE: u32 = 8;
pub const IS_UNDEF: u32 = 0;
@ -20,7 +20,7 @@ pub const IS_CALLABLE: u32 = 12;
pub const IS_VOID: u32 = 14;
pub const IS_MIXED: u32 = 16;
pub const IS_PTR: u32 = 13;
pub const _IS_BOOL: u32 = 18;
pub const _IS_BOOL: u32 = 17;
pub const Z_TYPE_FLAGS_SHIFT: u32 = 8;
pub const IS_TYPE_REFCOUNTED: u32 = 1;
pub const IS_TYPE_COLLECTABLE: u32 = 2;
@ -54,11 +54,13 @@ 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_PROPERTY_TYPES_RESOLVED: u32 = 32768;
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;
pub const ZEND_ACC_NEARLY_LINKED: u32 = 1048576;
pub const ZEND_ACC_NOT_SERIALIZABLE: u32 = 536870912;
pub const ZEND_ACC_HAS_UNLINKED_USES: u32 = 2097152;
pub const ZEND_ACC_DEPRECATED: u32 = 2048;
pub const ZEND_ACC_RETURN_REFERENCE: u32 = 4096;
pub const ZEND_ACC_HAS_RETURN_TYPE: u32 = 8192;
@ -77,9 +79,9 @@ pub const ZEND_ACC_DONE_PASS_TWO: u32 = 33554432;
pub const ZEND_ACC_HEAP_RT_CACHE: u32 = 67108864;
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 = 20220829;
pub const _ZEND_SEND_MODE_SHIFT: u32 = 24;
pub const _ZEND_IS_VARIADIC_BIT: u32 = 67108864;
pub const ZEND_MODULE_API_NO: u32 = 20200930;
pub const USING_ZTS: u32 = 0;
pub const MAY_BE_BOOL: u32 = 12;
pub const MAY_BE_ANY: u32 = 1022;
@ -180,6 +182,7 @@ pub union _zval_struct__bindgen_ty_2 {
pub num_args: u32,
pub fe_pos: u32,
pub fe_iter_idx: u32,
pub access_flags: u32,
pub property_guard: u32,
pub constant_flags: u32,
pub extra: u32,
@ -221,7 +224,7 @@ pub struct _zend_array {
pub gc: zend_refcounted_h,
pub u: _zend_array__bindgen_ty_1,
pub nTableMask: u32,
pub __bindgen_anon_1: _zend_array__bindgen_ty_2,
pub arData: *mut Bucket,
pub nNumUsed: u32,
pub nNumOfElements: u32,
pub nTableSize: u32,
@ -243,13 +246,6 @@ 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)]
@ -271,7 +267,7 @@ pub struct _zend_object {
#[derive(Copy, Clone)]
pub struct _zend_resource {
pub gc: zend_refcounted_h,
pub handle: zend_long,
pub handle: ::std::os::raw::c_int,
pub type_: ::std::os::raw::c_int,
pub ptr: *mut ::std::os::raw::c_void,
}
@ -293,22 +289,10 @@ pub struct _zend_ast_ref {
pub gc: zend_refcounted_h,
}
extern "C" {
pub fn _emalloc(
size: usize,
__zend_filename: *const ::std::os::raw::c_char,
__zend_lineno: u32,
__zend_orig_filename: *const ::std::os::raw::c_char,
__zend_orig_lineno: u32,
) -> *mut ::std::os::raw::c_void;
pub fn _emalloc(size: usize) -> *mut ::std::os::raw::c_void;
}
extern "C" {
pub fn _efree(
ptr: *mut ::std::os::raw::c_void,
__zend_filename: *const ::std::os::raw::c_char,
__zend_lineno: u32,
__zend_orig_filename: *const ::std::os::raw::c_char,
__zend_orig_lineno: u32,
);
pub fn _efree(ptr: *mut ::std::os::raw::c_void);
}
extern "C" {
pub fn __zend_malloc(len: usize) -> *mut ::std::os::raw::c_void;
@ -393,7 +377,7 @@ extern "C" {
pub fn zend_hash_get_current_key_zval_ex(
ht: *const HashTable,
key: *mut zval,
pos: *const HashPosition,
pos: *mut HashPosition,
);
}
extern "C" {
@ -476,15 +460,6 @@ 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],
}
@ -528,44 +503,6 @@ pub struct _zend_trait_alias {
}
pub type zend_trait_alias = _zend_trait_alias;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
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)]
#[derive(Debug, Copy, Clone)]
pub struct _zend_class_dependency {
pub name: *mut zend_string,
pub ce: *mut zend_class_entry,
}
pub type zend_class_dependency = _zend_class_dependency;
pub type zend_inheritance_cache_entry = _zend_inheritance_cache_entry;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _zend_error_info {
pub type_: ::std::os::raw::c_int,
pub lineno: u32,
pub filename: *mut zend_string,
pub message: *mut zend_string,
}
pub type zend_error_info = _zend_error_info;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _zend_inheritance_cache_entry {
pub next: *mut zend_inheritance_cache_entry,
pub ce: *mut zend_class_entry,
pub parent: *mut zend_class_entry,
pub dependencies: *mut zend_class_dependency,
pub dependencies_count: u32,
pub num_warnings: u32,
pub warnings: *mut *mut zend_error_info,
pub traits_and_interfaces: [*mut zend_class_entry; 1usize],
}
#[repr(C)]
pub struct _zend_class_entry {
pub type_: ::std::os::raw::c_char,
pub name: *mut zend_string,
@ -576,12 +513,10 @@ 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 zval,
pub static_members_table__ptr: *mut *mut zval,
pub function_table: HashTable,
pub properties_info: HashTable,
pub constants_table: HashTable,
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,
pub destructor: *mut zend_function,
@ -597,7 +532,6 @@ 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(
@ -636,8 +570,6 @@ pub struct _zend_class_entry {
pub trait_aliases: *mut *mut zend_trait_alias,
pub trait_precedences: *mut *mut zend_trait_precedence,
pub attributes: *mut HashTable,
pub enum_backing_type: u32,
pub backed_enum_table: *mut HashTable,
pub info: _zend_class_entry__bindgen_ty_4,
}
#[repr(C)]
@ -779,10 +711,10 @@ pub type zend_object_get_method_t = ::std::option::Option<
>;
pub type zend_object_get_constructor_t =
::std::option::Option<unsafe extern "C" fn(object: *mut zend_object) -> *mut zend_function>;
pub type zend_object_free_obj_t =
::std::option::Option<unsafe extern "C" fn(object: *mut zend_object)>;
pub type zend_object_dtor_obj_t =
::std::option::Option<unsafe extern "C" fn(object: *mut zend_object)>;
pub type zend_object_free_obj_t =
::std::option::Option<unsafe extern "C" fn(object: *mut zend_object)>;
pub type zend_object_clone_obj_t =
::std::option::Option<unsafe extern "C" fn(object: *mut zend_object) -> *mut zend_object>;
pub type zend_object_get_class_name_t =
@ -795,10 +727,10 @@ pub type zend_object_cast_t = ::std::option::Option<
readobj: *mut zend_object,
retval: *mut zval,
type_: ::std::os::raw::c_int,
) -> zend_result,
) -> ::std::os::raw::c_int,
>;
pub type zend_object_count_elements_t = ::std::option::Option<
unsafe extern "C" fn(object: *mut zend_object, count: *mut zend_long) -> zend_result,
unsafe extern "C" fn(object: *mut zend_object, count: *mut zend_long) -> ::std::os::raw::c_int,
>;
pub type zend_object_get_closure_t = ::std::option::Option<
unsafe extern "C" fn(
@ -806,8 +738,8 @@ pub type zend_object_get_closure_t = ::std::option::Option<
ce_ptr: *mut *mut zend_class_entry,
fptr_ptr: *mut *mut zend_function,
obj_ptr: *mut *mut zend_object,
check_only: bool,
) -> zend_result,
check_only: zend_bool,
) -> ::std::os::raw::c_int,
>;
pub type zend_object_get_gc_t = ::std::option::Option<
unsafe extern "C" fn(
@ -822,7 +754,7 @@ pub type zend_object_do_operation_t = ::std::option::Option<
result: *mut zval,
op1: *mut zval,
op2: *mut zval,
) -> zend_result,
) -> ::std::os::raw::c_int,
>;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@ -885,7 +817,7 @@ extern "C" {
) -> ::std::os::raw::c_int;
}
extern "C" {
pub fn zend_is_identical(op1: *mut zval, op2: *mut zval) -> bool;
pub fn zend_is_identical(op1: *mut zval, op2: *mut zval) -> zend_bool;
}
extern "C" {
pub fn zend_is_true(op: *mut zval) -> ::std::os::raw::c_int;
@ -973,13 +905,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 static_variables_ptr__ptr: *mut HashTable,
pub run_time_cache__ptr: *mut *mut *mut ::std::os::raw::c_void,
pub static_variables_ptr__ptr: *mut *mut HashTable,
pub static_variables: *mut HashTable,
pub vars: *mut *mut zend_string,
pub refcount: *mut u32,
@ -992,9 +924,7 @@ pub struct _zend_op_array {
pub line_end: u32,
pub doc_comment: *mut zend_string,
pub last_literal: ::std::os::raw::c_int,
pub num_dynamic_func_defs: u32,
pub literals: *mut zval,
pub dynamic_func_defs: *mut *mut zend_op_array,
pub reserved: [*mut ::std::os::raw::c_void; 6usize],
}
pub type zif_handler = ::std::option::Option<
@ -1013,8 +943,6 @@ 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],
@ -1042,8 +970,6 @@ 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 {
@ -1064,12 +990,6 @@ 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,
@ -1104,18 +1024,6 @@ extern "C" {
pub type zend_vm_stack = *mut _zend_vm_stack;
pub type zend_ini_entry = _zend_ini_entry;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _zend_fiber_context {
_unused: [u8; 0],
}
pub type zend_fiber_context = _zend_fiber_context;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct _zend_fiber {
_unused: [u8; 0],
}
pub type zend_fiber = _zend_fiber;
#[repr(C)]
pub struct _zend_executor_globals {
pub uninitialized_zval: zval,
pub error_zval: zval,
@ -1143,10 +1051,10 @@ pub struct _zend_executor_globals {
pub persistent_functions_count: u32,
pub persistent_classes_count: u32,
pub in_autoload: *mut HashTable,
pub full_tables_cleanup: bool,
pub no_extensions: bool,
pub vm_interrupt: zend_atomic_bool,
pub timed_out: zend_atomic_bool,
pub full_tables_cleanup: zend_bool,
pub no_extensions: zend_bool,
pub vm_interrupt: zend_bool,
pub timed_out: zend_bool,
pub hard_timeout: zend_long,
pub regular_list: HashTable,
pub persistent_list: HashTable,
@ -1159,7 +1067,7 @@ pub struct _zend_executor_globals {
pub error_handling: zend_error_handling_t,
pub exception_class: *mut zend_class_entry,
pub timeout_seconds: zend_long,
pub capture_warnings_during_sccp: ::std::os::raw::c_int,
pub lambda_count: ::std::os::raw::c_int,
pub ini_directives: *mut HashTable,
pub modified_ini_directives: *mut HashTable,
pub error_reporting_ini_entry: *mut zend_ini_entry,
@ -1169,7 +1077,7 @@ pub struct _zend_executor_globals {
pub opline_before_exception: *const zend_op,
pub exception_op: [zend_op; 3usize],
pub current_module: *mut _zend_module_entry,
pub active: bool,
pub active: zend_bool,
pub flags: zend_uchar,
pub assertions: zend_long,
pub ht_iterators_count: u32,
@ -1180,18 +1088,9 @@ pub struct _zend_executor_globals {
pub trampoline: zend_function,
pub call_trampoline_op: zend_op,
pub weakrefs: HashTable,
pub exception_ignore_args: bool,
pub exception_ignore_args: zend_bool,
pub exception_string_param_max_len: zend_long,
pub get_gc_buffer: zend_get_gc_buffer,
pub main_fiber_context: *mut zend_fiber_context,
pub current_fiber_context: *mut zend_fiber_context,
pub active_fiber: *mut zend_fiber,
pub fiber_stack_size: zend_long,
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;
@ -1288,7 +1187,7 @@ extern "C" {
callable: *mut zval,
check_flags: u32,
callable_name: *mut *mut zend_string,
) -> bool;
) -> zend_bool;
}
extern "C" {
pub fn zend_declare_property(
@ -1491,7 +1390,7 @@ extern "C" {
pub fn zend_register_bool_constant(
name: *const ::std::os::raw::c_char,
name_len: usize,
bval: bool,
bval: zend_bool,
flags: ::std::os::raw::c_int,
module_number: ::std::os::raw::c_int,
);
@ -1600,3 +1499,20 @@ extern "C" {
extern "C" {
pub static mut zend_ce_stringable: *mut zend_class_entry;
}
extern "C" {
pub fn zend_class_serialize_deny(
object: *mut zval,
buffer: *mut *mut ::std::os::raw::c_uchar,
buf_len: *mut usize,
data: *mut zend_serialize_data,
) -> ::std::os::raw::c_int;
}
extern "C" {
pub fn zend_class_unserialize_deny(
object: *mut zval,
ce: *mut zend_class_entry,
buf: *const ::std::os::raw::c_uchar,
buf_len: usize,
data: *mut zend_unserialize_data,
) -> ::std::os::raw::c_int;
}

View File

@ -51,3 +51,16 @@ php_core_globals *ext_php_rs_process_globals() {
return &core_globals;
#endif
}
sapi_globals_struct *ext_php_rs_sapi_globals() {
#ifdef ZTS
#ifdef ZEND_ENABLE_STATIC_TSRMLS_CACHE
return TSRMG_FAST_BULK_STATIC(sapi_globals_offset, sapi_globals_struct);
#else
return TSRMG_FAST_BULK(sapi_globals_offset, sapi_globals_struct *);
#endif
#else
return &sapi_globals;
#endif
}

View File

@ -20,6 +20,7 @@
#include "zend_exceptions.h"
#include "zend_inheritance.h"
#include "zend_interfaces.h"
#include "SAPI.h"
zend_string *ext_php_rs_zend_string_init(const char *str, size_t len, bool persistent);
void ext_php_rs_zend_string_release(zend_string *zs);
@ -31,3 +32,4 @@ void *ext_php_rs_zend_object_alloc(size_t obj_size, zend_class_entry *ce);
void ext_php_rs_zend_object_release(zend_object *obj);
zend_executor_globals *ext_php_rs_executor_globals();
php_core_globals *ext_php_rs_process_globals();
sapi_globals_struct *ext_php_rs_sapi_globals();

View File

@ -6,9 +6,9 @@ use parking_lot::{const_rwlock, RwLock, RwLockReadGuard, RwLockWriteGuard};
use crate::boxed::ZBox;
use crate::ffi::{
_zend_executor_globals, ext_php_rs_executor_globals, ext_php_rs_process_globals,
php_core_globals, TRACK_VARS_COOKIE, TRACK_VARS_ENV, TRACK_VARS_FILES, TRACK_VARS_GET,
TRACK_VARS_POST, TRACK_VARS_REQUEST, TRACK_VARS_SERVER,
_zend_executor_globals, ext_php_rs_executor_globals, ext_php_rs_process_globals, ext_php_rs_sapi_globals,
php_core_globals, sapi_globals_struct, TRACK_VARS_COOKIE, TRACK_VARS_ENV, TRACK_VARS_FILES, TRACK_VARS_GET,
TRACK_VARS_POST, TRACK_VARS_REQUEST, TRACK_VARS_SERVER
};
use crate::types::{ZendHashTable, ZendObject};
@ -157,12 +157,100 @@ impl ProcessGlobals {
}
}
/// Stores global variables used in the SAPI.
pub type SapiGlobals = sapi_globals_struct;
impl SapiGlobals {
/// Returns a reference to the PHP process globals.
///
/// The process globals are guarded by a RwLock. There can be multiple
/// immutable references at one time but only ever one mutable reference.
/// Attempting to retrieve the globals while already holding the global
/// guard will lead to a deadlock. Dropping the globals guard will release
/// the lock.
pub fn get() -> GlobalReadGuard<Self> {
// SAFETY: PHP executor globals are statically declared therefore should never
// return an invalid pointer.
let globals = unsafe { &*ext_php_rs_sapi_globals() };
let guard = SAPI_GLOBALS_LOCK.read();
GlobalReadGuard { globals, guard }
}
/// Returns a mutable reference to the PHP executor globals.
///
/// The executor globals are guarded by a RwLock. There can be multiple
/// immutable references at one time but only ever one mutable reference.
/// Attempting to retrieve the globals while already holding the global
/// guard will lead to a deadlock. Dropping the globals guard will release
/// the lock.
pub fn get_mut() -> GlobalWriteGuard<Self> {
// SAFETY: PHP executor globals are statically declared therefore should never
// return an invalid pointer.
let globals = unsafe { &mut *ext_php_rs_sapi_globals() };
let guard = SAPI_GLOBALS_LOCK.write();
GlobalWriteGuard { globals, guard }
}
/// Get the HTTP Server variables. Equivalent of $_SERVER.
pub fn http_server_vars(&self) -> Option<&ZendHashTable> {
if self.http_globals[TRACK_VARS_SERVER as usize].is_array() {
self.http_globals[TRACK_VARS_SERVER as usize].array()
} else {
None
}
}
/// Get the HTTP POST variables. Equivalent of $_POST.
pub fn http_post_vars(&self) -> &ZendHashTable {
self.http_globals[TRACK_VARS_POST as usize]
.array()
.expect("Type is not a ZendArray")
}
/// Get the HTTP GET variables. Equivalent of $_GET.
pub fn http_get_vars(&self) -> &ZendHashTable {
self.http_globals[TRACK_VARS_GET as usize]
.array()
.expect("Type is not a ZendArray")
}
/// Get the HTTP Cookie variables. Equivalent of $_COOKIE.
pub fn http_cookie_vars(&self) -> &ZendHashTable {
self.http_globals[TRACK_VARS_COOKIE as usize]
.array()
.expect("Type is not a ZendArray")
}
/// Get the HTTP Request variables. Equivalent of $_REQUEST.
pub fn http_request_vars(&self) -> &ZendHashTable {
self.http_globals[TRACK_VARS_REQUEST as usize]
.array()
.expect("Type is not a ZendArray")
}
/// Get the HTTP Environment variables. Equivalent of $_ENV.
pub fn http_env_vars(&self) -> &ZendHashTable {
self.http_globals[TRACK_VARS_ENV as usize]
.array()
.expect("Type is not a ZendArray")
}
/// Get the HTTP Files variables. Equivalent of $_FILES.
pub fn http_files_vars(&self) -> &ZendHashTable {
self.http_globals[TRACK_VARS_FILES as usize]
.array()
.expect("Type is not a ZendArray")
}
}
/// Executor globals rwlock.
///
/// PHP provides no indication if the executor globals are being accessed so
/// this is only effective on the Rust side.
static GLOBALS_LOCK: RwLock<()> = const_rwlock(());
static PROCESS_GLOBALS_LOCK: RwLock<()> = const_rwlock(());
static SAPI_GLOBALS_LOCK: RwLock<()> = const_rwlock(());
/// Wrapper guard that contains a reference to a given type `T`. Dropping a
/// guard releases the lock on the relevant rwlock.