Skip to content

Commit 2bf8718

Browse files
authored
Merge pull request #264 from nicelocal/func
Add zend_function wrapper, try_call_method zval/object methods
2 parents acd3369 + 4f1565f commit 2bf8718

File tree

20 files changed

+327
-13
lines changed

20 files changed

+327
-13
lines changed

allowed_bindings.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ bind! {
5555
zend_array_destroy,
5656
zend_array_dup,
5757
zend_call_known_function,
58+
zend_fetch_function_str,
59+
zend_hash_str_find_ptr_lc,
5860
zend_ce_argument_count_error,
5961
zend_ce_arithmetic_error,
6062
zend_ce_compile_error,

crates/cli/src/ext.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use anyhow::{Context, Result};
44
use ext_php_rs::describe::Description;
55
use libloading::os::unix::{Library, Symbol};
66

7+
#[allow(improper_ctypes_definitions)]
78
pub struct Ext {
89
// These need to be here to keep the libraries alive. The extension library needs to be alive
910
// to access the describe function. Missing here is the lifetime on `Symbol<'a, fn() ->

docsrs_bindings.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ pub const CONST_CS: u32 = 0;
105105
pub const CONST_PERSISTENT: u32 = 1;
106106
pub const CONST_NO_FILE_CACHE: u32 = 2;
107107
pub const CONST_DEPRECATED: u32 = 4;
108+
#[repr(C)]
109+
#[derive(Debug, Copy, Clone)]
110+
pub struct __sigset_t {
111+
pub __val: [::std::os::raw::c_ulong; 16usize],
112+
}
108113
pub type zend_long = i64;
109114
pub type zend_ulong = u64;
110115
pub type zend_uchar = ::std::os::raw::c_uchar;
@@ -405,6 +410,13 @@ extern "C" {
405410
extern "C" {
406411
pub fn zend_array_destroy(ht: *mut HashTable);
407412
}
413+
extern "C" {
414+
pub fn zend_hash_str_find_ptr_lc(
415+
ht: *const HashTable,
416+
str_: *const ::std::os::raw::c_char,
417+
len: usize,
418+
) -> *mut ::std::os::raw::c_void;
419+
}
408420
extern "C" {
409421
pub fn gc_possible_root(ref_: *mut zend_refcounted);
410422
}
@@ -1049,7 +1061,15 @@ pub struct _zend_execute_data {
10491061
pub run_time_cache: *mut *mut ::std::os::raw::c_void,
10501062
pub extra_named_params: *mut zend_array,
10511063
}
1052-
pub type sigjmp_buf = [::std::os::raw::c_int; 49usize];
1064+
pub type __jmp_buf = [::std::os::raw::c_long; 8usize];
1065+
#[repr(C)]
1066+
#[derive(Debug, Copy, Clone)]
1067+
pub struct __jmp_buf_tag {
1068+
pub __jmpbuf: __jmp_buf,
1069+
pub __mask_was_saved: ::std::os::raw::c_int,
1070+
pub __saved_mask: __sigset_t,
1071+
}
1072+
pub type jmp_buf = [__jmp_buf_tag; 1usize];
10531073
pub type zend_executor_globals = _zend_executor_globals;
10541074
extern "C" {
10551075
pub static mut executor_globals: zend_executor_globals;
@@ -1119,7 +1139,7 @@ pub struct _zend_executor_globals {
11191139
pub symtable_cache_ptr: *mut *mut zend_array,
11201140
pub symbol_table: zend_array,
11211141
pub included_files: HashTable,
1122-
pub bailout: *mut sigjmp_buf,
1142+
pub bailout: *mut jmp_buf,
11231143
pub error_reporting: ::std::os::raw::c_int,
11241144
pub exit_status: ::std::os::raw::c_int,
11251145
pub function_table: *mut HashTable,
@@ -1262,6 +1282,12 @@ pub struct _zend_vm_stack {
12621282
pub end: *mut zval,
12631283
pub prev: zend_vm_stack,
12641284
}
1285+
extern "C" {
1286+
pub fn zend_fetch_function_str(
1287+
name: *const ::std::os::raw::c_char,
1288+
len: usize,
1289+
) -> *mut zend_function;
1290+
}
12651291
#[repr(C)]
12661292
#[derive(Copy, Clone)]
12671293
pub struct _zend_function_entry {

guide/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
- [Object](./types/object.md)
2424
- [Class Object](./types/class_object.md)
2525
- [Closure](./types/closure.md)
26+
- [Functions & methods](./types/functions.md)
2627
- [Macros](./macros/index.md)
2728
- [Module](./macros/module.md)
2829
- [Module Startup Function](./macros/module_startup.md)

guide/src/types/functions.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Functions & methods
2+
3+
PHP functions and methods are represented by the `Function` struct.
4+
5+
You can use the `try_from_function` and `try_from_method` methods to obtain a Function struct corresponding to the passed function or static method name.
6+
It's heavily recommended you reuse returned `Function` objects, to avoid the overhead of looking up the function/method name.
7+
8+
You may also use the infallible `from_function` and `from_method` variants, for example when working with native PHP functions/classes that are guaranteed to be always available.
9+
10+
```rust,no_run
11+
# #![cfg_attr(windows, feature(abi_vectorcall))]
12+
# extern crate ext_php_rs;
13+
use ext_php_rs::prelude::*;
14+
15+
use ext_php_rs::zend::Function;
16+
17+
#[php_function]
18+
pub fn test_function() -> () {
19+
let var_dump = Function::from_function("var_dump");
20+
let _ = var_dump.try_call(vec![&"abc"]);
21+
}
22+
23+
#[php_function]
24+
pub fn test_method() -> () {
25+
let f = Function::from_method("ClassName", "staticMethod");
26+
let _ = f.try_call(vec![&"abc"]);
27+
}
28+
29+
# fn main() {}
30+
```

guide/src/types/object.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,25 @@ object.
1515

1616
## Examples
1717

18+
### Calling a method
19+
20+
```rust,no_run
21+
# #![cfg_attr(windows, feature(abi_vectorcall))]
22+
# extern crate ext_php_rs;
23+
use ext_php_rs::{prelude::*, types::ZendObject};
24+
25+
// Take an object reference and also return it.
26+
#[php_function]
27+
pub fn take_obj(obj: &mut ZendObject) -> () {
28+
let _ = obj.try_call_method("hello", vec![&"arg1", &"arg2"]);
29+
}
30+
# #[php_module]
31+
# pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
32+
# module
33+
# }
34+
# fn main() {}
35+
```
36+
1837
### Taking an object reference
1938

2039
```rust,no_run

src/args.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ impl<'a> Arg<'a> {
123123
/// # Parameters
124124
///
125125
/// * `params` - A list of parameters to call the function with.
126+
#[inline(always)]
126127
pub fn try_call(&self, params: Vec<&dyn IntoZvalDyn>) -> Result<Zval> {
127128
self.zval.as_ref().ok_or(Error::Callable)?.try_call(params)
128129
}

src/describe/abi.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ impl<T> Deref for Vec<T> {
3232

3333
impl<T> Drop for Vec<T> {
3434
fn drop(&mut self) {
35-
unsafe { Box::from_raw(std::ptr::slice_from_raw_parts_mut(self.ptr, self.len)) };
35+
unsafe {
36+
let _ = Box::from_raw(std::ptr::slice_from_raw_parts_mut(self.ptr, self.len));
37+
};
3638
}
3739
}
3840

src/describe/stub.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl ToStub for Module {
5252
// Inserts a value into the entries hashmap. Takes a key and an entry, creating
5353
// the internal vector if it doesn't already exist.
5454
let mut insert = |ns, entry| {
55-
let bucket = entries.entry(ns).or_insert_with(StdVec::new);
55+
let bucket = entries.entry(ns).or_default();
5656
bucket.push(entry);
5757
};
5858

src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ pub enum Error {
5757
InvalidUtf8,
5858
/// Could not call the given function.
5959
Callable,
60+
/// An object was expected.
61+
Object,
6062
/// An invalid exception type was thrown.
6163
InvalidException(ClassFlags),
6264
/// Converting integer arguments resulted in an overflow.
@@ -89,6 +91,7 @@ impl Display for Error {
8991
),
9092
Error::InvalidUtf8 => write!(f, "Invalid Utf8 byte sequence."),
9193
Error::Callable => write!(f, "Could not call given function."),
94+
Error::Object => write!(f, "An object was expected."),
9295
Error::InvalidException(flags) => {
9396
write!(f, "Invalid exception type was thrown: {flags:?}")
9497
}

0 commit comments

Comments
 (0)