mirror of
https://github.com/danog/ext-php-rs.git
synced 2024-11-30 04:39:04 +01:00
Merge branch 'master' into ini-definitions
This commit is contained in:
commit
7b47b46cfb
@ -46,6 +46,7 @@ bind! {
|
||||
// ext_php_rs_is_kown_valid_utf8,
|
||||
// ext_php_rs_set_kown_valid_utf8,
|
||||
object_properties_init,
|
||||
php_error_docref,
|
||||
php_info_print_table_end,
|
||||
php_info_print_table_header,
|
||||
php_info_print_table_row,
|
||||
@ -115,6 +116,21 @@ bind! {
|
||||
CONST_DEPRECATED,
|
||||
CONST_NO_FILE_CACHE,
|
||||
CONST_PERSISTENT,
|
||||
E_ERROR,
|
||||
E_WARNING,
|
||||
E_PARSE,
|
||||
E_NOTICE,
|
||||
E_CORE_ERROR,
|
||||
E_CORE_WARNING,
|
||||
E_COMPILE_ERROR,
|
||||
E_COMPILE_WARNING,
|
||||
E_USER_ERROR,
|
||||
E_USER_WARNING,
|
||||
E_USER_NOTICE,
|
||||
E_STRICT,
|
||||
E_RECOVERABLE_ERROR,
|
||||
E_DEPRECATED,
|
||||
E_USER_DEPRECATED,
|
||||
HT_MIN_SIZE,
|
||||
IS_ARRAY,
|
||||
IS_ARRAY_EX,
|
||||
@ -207,6 +223,9 @@ bind! {
|
||||
_ZEND_TYPE_NULLABLE_BIT,
|
||||
ts_rsrc_id,
|
||||
_ZEND_TYPE_NAME_BIT,
|
||||
ZEND_INTERNAL_FUNCTION,
|
||||
ZEND_USER_FUNCTION,
|
||||
ZEND_EVAL_CODE,
|
||||
zval_ptr_dtor,
|
||||
zend_refcounted_h,
|
||||
zend_is_true,
|
||||
@ -233,5 +252,7 @@ bind! {
|
||||
php_printf,
|
||||
__zend_malloc,
|
||||
tsrm_get_ls_cache,
|
||||
executor_globals_offset
|
||||
executor_globals_offset,
|
||||
zend_atomic_bool_store,
|
||||
zend_interrupt_function
|
||||
}
|
||||
|
@ -31,6 +31,21 @@ pub const IS_OBJECT_EX: u32 = 776;
|
||||
pub const IS_RESOURCE_EX: u32 = 265;
|
||||
pub const IS_REFERENCE_EX: u32 = 266;
|
||||
pub const IS_CONSTANT_AST_EX: u32 = 267;
|
||||
pub const E_ERROR: u32 = 1;
|
||||
pub const E_WARNING: u32 = 2;
|
||||
pub const E_PARSE: u32 = 4;
|
||||
pub const E_NOTICE: u32 = 8;
|
||||
pub const E_CORE_ERROR: u32 = 16;
|
||||
pub const E_CORE_WARNING: u32 = 32;
|
||||
pub const E_COMPILE_ERROR: u32 = 64;
|
||||
pub const E_COMPILE_WARNING: u32 = 128;
|
||||
pub const E_USER_ERROR: u32 = 256;
|
||||
pub const E_USER_WARNING: u32 = 512;
|
||||
pub const E_USER_NOTICE: u32 = 1024;
|
||||
pub const E_STRICT: u32 = 2048;
|
||||
pub const E_RECOVERABLE_ERROR: u32 = 4096;
|
||||
pub const E_DEPRECATED: u32 = 8192;
|
||||
pub const E_USER_DEPRECATED: u32 = 16384;
|
||||
pub const ZEND_PROPERTY_ISSET: u32 = 0;
|
||||
pub const ZEND_PROPERTY_EXISTS: u32 = 2;
|
||||
pub const ZEND_ACC_PUBLIC: u32 = 1;
|
||||
@ -76,6 +91,9 @@ pub const ZEND_ACC_GENERATOR: u32 = 16777216;
|
||||
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_INTERNAL_FUNCTION: u32 = 1;
|
||||
pub const ZEND_USER_FUNCTION: u32 = 2;
|
||||
pub const ZEND_EVAL_CODE: u32 = 4;
|
||||
pub const ZEND_ISEMPTY: u32 = 1;
|
||||
pub const _ZEND_SEND_MODE_SHIFT: u32 = 25;
|
||||
pub const _ZEND_IS_VARIADIC_BIT: u32 = 134217728;
|
||||
@ -659,6 +677,10 @@ pub struct _zend_class_entry__bindgen_ty_4__bindgen_ty_2 {
|
||||
pub builtin_functions: *const _zend_function_entry,
|
||||
pub module: *mut _zend_module_entry,
|
||||
}
|
||||
extern "C" {
|
||||
pub static mut zend_interrupt_function:
|
||||
::std::option::Option<unsafe extern "C" fn(execute_data: *mut zend_execute_data)>;
|
||||
}
|
||||
extern "C" {
|
||||
pub static mut zend_standard_class_def: *mut zend_class_entry;
|
||||
}
|
||||
@ -1042,6 +1064,9 @@ pub struct zend_atomic_bool_s {
|
||||
pub value: u8,
|
||||
}
|
||||
pub type zend_atomic_bool = zend_atomic_bool_s;
|
||||
extern "C" {
|
||||
pub fn zend_atomic_bool_store(obj: *mut zend_atomic_bool, desired: bool);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct _zend_stack {
|
||||
@ -1345,6 +1370,14 @@ extern "C" {
|
||||
extern "C" {
|
||||
pub fn php_printf(format: *const ::std::os::raw::c_char, ...) -> usize;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn php_error_docref(
|
||||
docref: *const ::std::os::raw::c_char,
|
||||
type_: ::std::os::raw::c_int,
|
||||
format: *const ::std::os::raw::c_char,
|
||||
...
|
||||
);
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct _zend_ini_entry_def {
|
||||
|
@ -126,6 +126,20 @@ impl ModuleBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the post request shutdown function for the extension.
|
||||
///
|
||||
/// This function can be useful if you need to do any final cleanup at the
|
||||
/// very end of a request, after all other resources have been released. For
|
||||
/// example, if your extension creates any persistent resources that last
|
||||
/// beyond a single request, you could use this function to clean those up.
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `func` - The function to be called when shutdown is requested.
|
||||
pub fn post_deactivate_function(mut self, func: extern "C" fn() -> i32) -> Self {
|
||||
self.module.post_deactivate_func = Some(func);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the extension information function for the extension.
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -218,3 +218,13 @@ impl<T: IntoZval + Clone> IntoZvalDyn for T {
|
||||
Self::TYPE
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoZvalDyn for Zval {
|
||||
fn as_zval(&self, _persistent: bool) -> Result<Zval> {
|
||||
Ok(self.shallow_clone())
|
||||
}
|
||||
|
||||
fn get_type(&self) -> DataType {
|
||||
self.get_type()
|
||||
}
|
||||
}
|
||||
|
23
src/error.rs
23
src/error.rs
@ -1,11 +1,16 @@
|
||||
//! Error and result types returned from the library functions.
|
||||
|
||||
use std::{error::Error as ErrorTrait, ffi::NulError, fmt::Display};
|
||||
use std::{
|
||||
error::Error as ErrorTrait,
|
||||
ffi::{CString, NulError},
|
||||
fmt::Display,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
boxed::ZBox,
|
||||
exception::PhpException,
|
||||
flags::{ClassFlags, DataType, ZvalTypeFlags},
|
||||
ffi::php_error_docref,
|
||||
flags::{ClassFlags, DataType, ErrorType, ZvalTypeFlags},
|
||||
types::ZendObject,
|
||||
};
|
||||
|
||||
@ -108,3 +113,17 @@ impl From<Error> for PhpException {
|
||||
Self::default(err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// Trigger an error that is reported in PHP the same way `trigger_error()` is.
|
||||
///
|
||||
/// See specific error type descriptions at <https://www.php.net/manual/en/errorfunc.constants.php>.
|
||||
pub fn php_error(type_: ErrorType, message: &str) {
|
||||
let c_string = match CString::new(message) {
|
||||
Ok(string) => string,
|
||||
Err(_) => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
unsafe { php_error_docref(std::ptr::null(), type_.bits() as _, c_string.as_ptr()) }
|
||||
}
|
||||
|
63
src/flags.rs
63
src/flags.rs
@ -5,22 +5,25 @@ 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,
|
||||
IS_REFERENCE, IS_RESOURCE, IS_STRING, IS_TRUE, IS_TYPE_COLLECTABLE, IS_TYPE_REFCOUNTED,
|
||||
IS_UNDEF, IS_VOID, PHP_INI_ALL, PHP_INI_PERDIR, PHP_INI_SYSTEM, PHP_INI_USER,
|
||||
ZEND_ACC_ABSTRACT, ZEND_ACC_ANON_CLASS, ZEND_ACC_CALL_VIA_TRAMPOLINE, ZEND_ACC_CHANGED,
|
||||
ZEND_ACC_CLOSURE, ZEND_ACC_CONSTANTS_UPDATED, ZEND_ACC_CTOR, ZEND_ACC_DEPRECATED,
|
||||
ZEND_ACC_DONE_PASS_TWO, ZEND_ACC_EARLY_BINDING, ZEND_ACC_FAKE_CLOSURE, ZEND_ACC_FINAL,
|
||||
ZEND_ACC_GENERATOR, ZEND_ACC_HAS_FINALLY_BLOCK, ZEND_ACC_HAS_RETURN_TYPE,
|
||||
CONST_CS, CONST_DEPRECATED, CONST_NO_FILE_CACHE, CONST_PERSISTENT, E_COMPILE_ERROR,
|
||||
E_COMPILE_WARNING, E_CORE_ERROR, E_CORE_WARNING, E_DEPRECATED, E_ERROR, E_NOTICE, E_PARSE,
|
||||
E_RECOVERABLE_ERROR, E_STRICT, E_USER_DEPRECATED, E_USER_ERROR, E_USER_NOTICE, E_USER_WARNING,
|
||||
E_WARNING, IS_ARRAY, IS_CALLABLE, IS_CONSTANT_AST, IS_DOUBLE, IS_FALSE, IS_LONG, IS_MIXED,
|
||||
IS_NULL, IS_OBJECT, IS_PTR, IS_REFERENCE, IS_RESOURCE, IS_STRING, IS_TRUE, IS_TYPE_COLLECTABLE,
|
||||
IS_TYPE_REFCOUNTED, IS_UNDEF, IS_VOID, PHP_INI_ALL, PHP_INI_PERDIR, PHP_INI_SYSTEM,
|
||||
PHP_INI_USER, ZEND_ACC_ABSTRACT, ZEND_ACC_ANON_CLASS, ZEND_ACC_CALL_VIA_TRAMPOLINE,
|
||||
ZEND_ACC_CHANGED, ZEND_ACC_CLOSURE, ZEND_ACC_CONSTANTS_UPDATED, ZEND_ACC_CTOR,
|
||||
ZEND_ACC_DEPRECATED, ZEND_ACC_DONE_PASS_TWO, ZEND_ACC_EARLY_BINDING, ZEND_ACC_FAKE_CLOSURE,
|
||||
ZEND_ACC_FINAL, ZEND_ACC_GENERATOR, ZEND_ACC_HAS_FINALLY_BLOCK, ZEND_ACC_HAS_RETURN_TYPE,
|
||||
ZEND_ACC_HAS_TYPE_HINTS, ZEND_ACC_HEAP_RT_CACHE, ZEND_ACC_IMMUTABLE,
|
||||
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_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_USES_THIS, ZEND_ACC_USE_GUARDS, ZEND_ACC_VARIADIC, ZEND_EVAL_CODE,
|
||||
ZEND_HAS_STATIC_IN_METHODS, ZEND_INTERNAL_FUNCTION, ZEND_USER_FUNCTION, Z_TYPE_FLAGS_SHIFT,
|
||||
_IS_BOOL,
|
||||
};
|
||||
|
||||
use std::{convert::TryFrom, fmt::Display};
|
||||
@ -182,6 +185,46 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
/// Represents error types when used via php_error_docref for example.
|
||||
pub struct ErrorType: u32 {
|
||||
const Error = E_ERROR;
|
||||
const Warning = E_WARNING;
|
||||
const Parse = E_PARSE;
|
||||
const Notice = E_NOTICE;
|
||||
const CoreError = E_CORE_ERROR;
|
||||
const CoreWarning = E_CORE_WARNING;
|
||||
const CompileError = E_COMPILE_ERROR;
|
||||
const CompileWarning = E_COMPILE_WARNING;
|
||||
const UserError = E_USER_ERROR;
|
||||
const UserWarning = E_USER_WARNING;
|
||||
const UserNotice = E_USER_NOTICE;
|
||||
const Strict = E_STRICT;
|
||||
const RecoverableError = E_RECOVERABLE_ERROR;
|
||||
const Deprecated = E_DEPRECATED;
|
||||
const UserDeprecated = E_USER_DEPRECATED;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
|
||||
pub enum FunctionType {
|
||||
Internal,
|
||||
User,
|
||||
Eval,
|
||||
}
|
||||
|
||||
impl From<u8> for FunctionType {
|
||||
#[allow(clippy::bad_bit_mask)]
|
||||
fn from(value: u8) -> Self {
|
||||
match value as _ {
|
||||
ZEND_INTERNAL_FUNCTION => Self::Internal,
|
||||
ZEND_USER_FUNCTION => Self::User,
|
||||
ZEND_EVAL_CODE => Self::Eval,
|
||||
_ => panic!("Unknown function type: {}", value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Valid data types for PHP.
|
||||
#[repr(C, u8)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
|
@ -79,6 +79,10 @@ impl ClassEntry {
|
||||
Self::try_find(name.as_str().ok()?)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> Option<&str> {
|
||||
unsafe { self.name.as_ref().and_then(|s| s.as_str().ok()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for ClassEntry {
|
||||
|
@ -6,8 +6,9 @@ use std::ops::{Deref, DerefMut};
|
||||
use parking_lot::{const_rwlock, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
use crate::boxed::ZBox;
|
||||
#[cfg(php82)]
|
||||
use crate::ffi::zend_atomic_bool_store;
|
||||
use crate::ffi::{_zend_executor_globals, ext_php_rs_executor_globals, zend_ini_entry};
|
||||
|
||||
use crate::types::{ZendHashTable, ZendObject};
|
||||
|
||||
/// Stores global variables used in the PHP executor.
|
||||
@ -76,6 +77,11 @@ impl ExecutorGlobals {
|
||||
ini_hash_map
|
||||
}
|
||||
|
||||
/// Attempts to retrieve the global constants table.
|
||||
pub fn constants(&self) -> Option<&ZendHashTable> {
|
||||
unsafe { self.zend_constants.as_ref() }
|
||||
}
|
||||
|
||||
/// Attempts to extract the last PHP exception captured by the interpreter.
|
||||
/// Returned inside a [`ZBox`].
|
||||
///
|
||||
@ -91,6 +97,21 @@ impl ExecutorGlobals {
|
||||
// SAFETY: `as_mut` checks for null.
|
||||
Some(unsafe { ZBox::from_raw(exception_ptr.as_mut()?) })
|
||||
}
|
||||
|
||||
/// Request an interrupt of the PHP VM. This will call the registered
|
||||
/// interrupt handler function.
|
||||
/// set with [`crate::ffi::zend_interrupt_function`].
|
||||
pub fn request_interrupt(&mut self) {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(php82)] {
|
||||
unsafe {
|
||||
zend_atomic_bool_store(&mut self.vm_interrupt, true);
|
||||
}
|
||||
} else {
|
||||
self.vm_interrupt = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Executor globals rwlock.
|
||||
|
Loading…
Reference in New Issue
Block a user