mirror of
https://github.com/danog/ext-php-rs.git
synced 2024-12-11 16:49:53 +01:00
feat(sapi): split try_catch / try_catch_first, global feature for test
This commit is contained in:
parent
4f74bfcd8a
commit
411ee6c176
@ -90,7 +90,7 @@ impl Embed {
|
|||||||
zend_stream_init_filename(&mut file_handle, path.as_ptr());
|
zend_stream_init_filename(&mut file_handle, path.as_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
let exec_result = try_catch(|| unsafe { php_execute_script(&mut file_handle) }, false);
|
let exec_result = try_catch(|| unsafe { php_execute_script(&mut file_handle) });
|
||||||
|
|
||||||
match exec_result {
|
match exec_result {
|
||||||
Err(_) => Err(EmbedError::CatchError),
|
Err(_) => Err(EmbedError::CatchError),
|
||||||
@ -184,16 +184,13 @@ impl Embed {
|
|||||||
|
|
||||||
let mut result = Zval::new();
|
let mut result = Zval::new();
|
||||||
|
|
||||||
let exec_result = try_catch(
|
let exec_result = try_catch(|| unsafe {
|
||||||
|| unsafe {
|
|
||||||
zend_eval_string(
|
zend_eval_string(
|
||||||
cstr.as_ptr() as *const c_char,
|
cstr.as_ptr() as *const c_char,
|
||||||
&mut result,
|
&mut result,
|
||||||
b"run\0".as_ptr() as *const _,
|
b"run\0".as_ptr() as *const _,
|
||||||
)
|
)
|
||||||
},
|
});
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
match exec_result {
|
match exec_result {
|
||||||
Err(_) => Err(EmbedError::CatchError),
|
Err(_) => Err(EmbedError::CatchError),
|
||||||
|
@ -25,7 +25,7 @@ pub use ini_entry_def::IniEntryDef;
|
|||||||
pub use module::ModuleEntry;
|
pub use module::ModuleEntry;
|
||||||
#[cfg(feature = "embed")]
|
#[cfg(feature = "embed")]
|
||||||
pub(crate) use try_catch::panic_wrapper;
|
pub(crate) use try_catch::panic_wrapper;
|
||||||
pub use try_catch::{bailout, try_catch};
|
pub use try_catch::{bailout, try_catch, try_catch_first};
|
||||||
|
|
||||||
// Used as the format string for `php_printf`.
|
// Used as the format string for `php_printf`.
|
||||||
const FORMAT_STR: &[u8] = b"%s\0";
|
const FORMAT_STR: &[u8] = b"%s\0";
|
||||||
|
@ -28,10 +28,28 @@ pub(crate) unsafe extern "C" fn panic_wrapper<R, F: FnMut() -> R + RefUnwindSafe
|
|||||||
///
|
///
|
||||||
/// * `Ok(R)` - The result of the function
|
/// * `Ok(R)` - The result of the function
|
||||||
/// * `Err(CatchError)` - A bailout occurred during the execution
|
/// * `Err(CatchError)` - A bailout occurred during the execution
|
||||||
pub fn try_catch<R, F: FnMut() -> R + RefUnwindSafe>(
|
pub fn try_catch<R, F: FnMut() -> R + RefUnwindSafe>(func: F) -> Result<R, CatchError> {
|
||||||
func: F,
|
do_try_catch(func, false)
|
||||||
first: bool,
|
}
|
||||||
) -> Result<R, CatchError> {
|
|
||||||
|
/// PHP propose a try catch mechanism in C using setjmp and longjmp (bailout)
|
||||||
|
/// It store the arg of setjmp into the bailout field of the global executor
|
||||||
|
/// If a bailout is triggered, the executor will jump to the setjmp and restore the previous setjmp
|
||||||
|
///
|
||||||
|
/// try_catch_first allow to use this mechanism
|
||||||
|
///
|
||||||
|
/// This functions differs from ['try_catch'] as it also initialize the bailout mechanism
|
||||||
|
/// for the first time
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// * `Ok(R)` - The result of the function
|
||||||
|
/// * `Err(CatchError)` - A bailout occurred during the execution
|
||||||
|
pub fn try_catch_first<R, F: FnMut() -> R + RefUnwindSafe>(func: F) -> Result<R, CatchError> {
|
||||||
|
do_try_catch(func, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_try_catch<R, F: FnMut() -> R + RefUnwindSafe>(func: F, first: bool) -> Result<R, CatchError> {
|
||||||
let mut panic_ptr = null_mut();
|
let mut panic_ptr = null_mut();
|
||||||
let has_bailout = unsafe {
|
let has_bailout = unsafe {
|
||||||
if first {
|
if first {
|
||||||
@ -91,8 +109,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_catch() {
|
fn test_catch() {
|
||||||
Embed::run(|| {
|
Embed::run(|| {
|
||||||
let catch = try_catch(
|
let catch = try_catch(|| {
|
||||||
|| {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
bailout();
|
bailout();
|
||||||
}
|
}
|
||||||
@ -101,9 +118,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
assert!(false);
|
assert!(false);
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(catch.is_err());
|
assert!(catch.is_err());
|
||||||
});
|
});
|
||||||
@ -112,12 +127,9 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_no_catch() {
|
fn test_no_catch() {
|
||||||
Embed::run(|| {
|
Embed::run(|| {
|
||||||
let catch = try_catch(
|
let catch = try_catch(|| {
|
||||||
|| {
|
|
||||||
assert!(true);
|
assert!(true);
|
||||||
},
|
});
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(catch.is_ok());
|
assert!(catch.is_ok());
|
||||||
});
|
});
|
||||||
@ -141,24 +153,18 @@ mod tests {
|
|||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_panic() {
|
fn test_panic() {
|
||||||
Embed::run(|| {
|
Embed::run(|| {
|
||||||
let _ = try_catch(
|
let _ = try_catch(|| {
|
||||||
|| {
|
|
||||||
panic!("should panic");
|
panic!("should panic");
|
||||||
},
|
});
|
||||||
false,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_return() {
|
fn test_return() {
|
||||||
let foo = Embed::run(|| {
|
let foo = Embed::run(|| {
|
||||||
let result = try_catch(
|
let result = try_catch(|| {
|
||||||
|| {
|
|
||||||
return "foo";
|
return "foo";
|
||||||
},
|
});
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
|
|
||||||
@ -172,17 +178,14 @@ mod tests {
|
|||||||
fn test_memory_leak() {
|
fn test_memory_leak() {
|
||||||
let mut ptr = null_mut();
|
let mut ptr = null_mut();
|
||||||
|
|
||||||
let _ = try_catch(
|
let _ = try_catch(|| {
|
||||||
|| {
|
|
||||||
let mut result = "foo".to_string();
|
let mut result = "foo".to_string();
|
||||||
ptr = &mut result;
|
ptr = &mut result;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
bailout();
|
bailout();
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check that the string is never released
|
// Check that the string is never released
|
||||||
let result = unsafe { &*ptr as &str };
|
let result = unsafe { &*ptr as &str };
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
#![cfg_attr(windows, feature(abi_vectorcall))]
|
#![cfg_attr(windows, feature(abi_vectorcall))]
|
||||||
|
#![cfg(feature = "embed")]
|
||||||
extern crate ext_php_rs;
|
extern crate ext_php_rs;
|
||||||
|
|
||||||
#[cfg(feature = "embed")]
|
|
||||||
use ext_php_rs::embed::Embed;
|
use ext_php_rs::embed::Embed;
|
||||||
#[cfg(feature = "embed")]
|
|
||||||
use ext_php_rs::ffi::zend_register_module_ex;
|
use ext_php_rs::ffi::zend_register_module_ex;
|
||||||
use ext_php_rs::prelude::*;
|
use ext_php_rs::prelude::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "embed")]
|
|
||||||
fn test_module() {
|
fn test_module() {
|
||||||
Embed::run(|| {
|
Embed::run(|| {
|
||||||
// Allow to load the module
|
// Allow to load the module
|
||||||
|
@ -1,25 +1,19 @@
|
|||||||
#![cfg_attr(windows, feature(abi_vectorcall))]
|
#![cfg_attr(windows, feature(abi_vectorcall))]
|
||||||
|
#![cfg(feature = "embed")]
|
||||||
extern crate ext_php_rs;
|
extern crate ext_php_rs;
|
||||||
|
|
||||||
#[cfg(feature = "embed")]
|
|
||||||
use std::ffi::c_char;
|
|
||||||
#[cfg(feature = "embed")]
|
|
||||||
use ext_php_rs::builders::SapiBuilder;
|
use ext_php_rs::builders::SapiBuilder;
|
||||||
#[cfg(feature = "embed")]
|
|
||||||
use ext_php_rs::embed::{ext_php_rs_sapi_startup, Embed};
|
use ext_php_rs::embed::{ext_php_rs_sapi_startup, Embed};
|
||||||
#[cfg(feature = "embed")]
|
|
||||||
use ext_php_rs::ffi::{
|
use ext_php_rs::ffi::{
|
||||||
php_module_shutdown, php_module_startup, php_request_shutdown, php_request_startup,
|
php_module_shutdown, php_module_startup, php_request_shutdown, php_request_startup,
|
||||||
sapi_shutdown, sapi_startup, ZEND_RESULT_CODE_SUCCESS,
|
sapi_shutdown, sapi_startup, ZEND_RESULT_CODE_SUCCESS,
|
||||||
};
|
};
|
||||||
use ext_php_rs::prelude::*;
|
use ext_php_rs::prelude::*;
|
||||||
#[cfg(feature = "embed")]
|
use ext_php_rs::zend::try_catch_first;
|
||||||
use ext_php_rs::zend::try_catch;
|
use std::ffi::c_char;
|
||||||
|
|
||||||
#[cfg(feature = "embed")]
|
|
||||||
static mut LAST_OUTPUT: String = String::new();
|
static mut LAST_OUTPUT: String = String::new();
|
||||||
|
|
||||||
#[cfg(feature = "embed")]
|
|
||||||
extern "C" fn output_tester(str: *const c_char, str_length: usize) -> usize {
|
extern "C" fn output_tester(str: *const c_char, str_length: usize) -> usize {
|
||||||
let char = unsafe { std::slice::from_raw_parts(str as *const u8, str_length) };
|
let char = unsafe { std::slice::from_raw_parts(str as *const u8, str_length) };
|
||||||
let string = String::from_utf8_lossy(char);
|
let string = String::from_utf8_lossy(char);
|
||||||
@ -34,7 +28,6 @@ extern "C" fn output_tester(str: *const c_char, str_length: usize) -> usize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "embed")]
|
|
||||||
fn test_sapi() {
|
fn test_sapi() {
|
||||||
let mut builder = SapiBuilder::new("test", "Test");
|
let mut builder = SapiBuilder::new("test", "Test");
|
||||||
builder = builder.ub_write_function(output_tester);
|
builder = builder.ub_write_function(output_tester);
|
||||||
@ -58,8 +51,7 @@ fn test_sapi() {
|
|||||||
|
|
||||||
assert_eq!(result, ZEND_RESULT_CODE_SUCCESS);
|
assert_eq!(result, ZEND_RESULT_CODE_SUCCESS);
|
||||||
|
|
||||||
let _ = try_catch(
|
let _ = try_catch_first(|| {
|
||||||
|| {
|
|
||||||
let result = Embed::eval("$foo = hello_world('foo');");
|
let result = Embed::eval("$foo = hello_world('foo');");
|
||||||
|
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
@ -75,9 +67,7 @@ fn test_sapi() {
|
|||||||
let result = Embed::eval("var_dump($foo);");
|
let result = Embed::eval("var_dump($foo);");
|
||||||
|
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
},
|
});
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
php_request_shutdown(std::ptr::null_mut());
|
php_request_shutdown(std::ptr::null_mut());
|
||||||
|
Loading…
Reference in New Issue
Block a user