mirror of
https://github.com/danog/ext-php-rs.git
synced 2025-01-22 21:11:45 +01:00
Created derive macro for ZendObjectHandler (#19)
* Initialize handlers on first touch In the process of turning the two macros into one derive proc macro * Changed the object handler macros into derive
This commit is contained in:
parent
ec87e0453a
commit
860ffb3587
@ -10,12 +10,10 @@ authors = ["David Cole <david.cole1340@gmail.com>"]
|
||||
edition = "2018"
|
||||
categories = ["api-bindings"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2.88"
|
||||
bitflags = "1.2.1"
|
||||
paste = "1.0"
|
||||
ext-php-rs-derive = { path = "./ext-php-rs-derive" }
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.53.1"
|
||||
|
@ -1,6 +1,5 @@
|
||||
use ext_php_rs::{
|
||||
call_user_func, info_table_end, info_table_row, info_table_start, object_handlers_init,
|
||||
object_override_handler,
|
||||
call_user_func, info_table_end, info_table_row, info_table_start,
|
||||
php::{
|
||||
args::{Arg, ArgParser},
|
||||
class::ClassBuilder,
|
||||
@ -11,6 +10,7 @@ use ext_php_rs::{
|
||||
module::{ModuleBuilder, ModuleEntry},
|
||||
types::{array::ZendHashTable, long::ZendLong, object::ZendClassObject, zval::Zval},
|
||||
},
|
||||
ZendObjectHandler,
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
@ -20,18 +20,16 @@ pub extern "C" fn php_module_info(_module: *mut ModuleEntry) {
|
||||
info_table_end!();
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, ZendObjectHandler)]
|
||||
struct Test {
|
||||
a: u32,
|
||||
b: u32,
|
||||
}
|
||||
object_override_handler!(Test);
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug, Default, ZendObjectHandler)]
|
||||
struct AnotherTest {
|
||||
x: u32,
|
||||
}
|
||||
object_override_handler!(AnotherTest);
|
||||
|
||||
impl Test {
|
||||
pub extern "C" fn constructor(execute_data: &mut ExecutionData, _retval: &mut Zval) {
|
||||
@ -40,7 +38,7 @@ impl Test {
|
||||
if x.is_none() {
|
||||
eprintln!("Object was none");
|
||||
} else {
|
||||
let obj = x.unwrap();
|
||||
// let obj = x.unwrap();
|
||||
println!("Object not none");
|
||||
}
|
||||
}
|
||||
@ -81,7 +79,7 @@ impl Default for Test {
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn module_init(_type: i32, _module_number: i32) -> i32 {
|
||||
object_handlers_init!(Test);
|
||||
// object_handlers_init!(Test);
|
||||
|
||||
ClassBuilder::new("TestClass")
|
||||
.method(
|
||||
|
17
ext-php-rs-derive/Cargo.toml
Normal file
17
ext-php-rs-derive/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "ext-php-rs-derive"
|
||||
description = "Derive macros for ext-php-rs."
|
||||
repository = "https://github.com/davidcole1340/ext-php-rs"
|
||||
homepage = "https://github.com/davidcole1340/ext-php-rs"
|
||||
license = "MIT"
|
||||
version = "0.0.2"
|
||||
authors = ["David Cole <david.cole1340@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = "1.0.68"
|
||||
quote = "1.0.9"
|
||||
proc-macro2 = "1.0.26"
|
45
ext-php-rs-derive/src/lib.rs
Normal file
45
ext-php-rs-derive/src/lib.rs
Normal file
@ -0,0 +1,45 @@
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::{Ident, Span};
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, DeriveInput};
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
/// Derives the implementation of `ZendObjectOverride` for the given structure.
|
||||
#[proc_macro_derive(ZendObjectHandler)]
|
||||
pub fn object_handler_derive(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let name = input.ident;
|
||||
let handlers = Ident::new(
|
||||
format!("__{}_OBJECT_HANDLERS", name).as_str(),
|
||||
Span::call_site(),
|
||||
);
|
||||
|
||||
let output = quote! {
|
||||
static mut #handlers: Option<
|
||||
*mut ::ext_php_rs::php::types::object::ZendObjectHandlers
|
||||
> = None;
|
||||
|
||||
impl ::ext_php_rs::php::types::object::ZendObjectOverride for #name {
|
||||
extern "C" fn create_object(
|
||||
ce: *mut ::ext_php_rs::php::class::ClassEntry,
|
||||
) -> *mut ::ext_php_rs::php::types::object::ZendObject {
|
||||
// SAFETY: The handlers are only modified once, when they are first accessed.
|
||||
// At the moment we only support single-threaded PHP installations therefore the pointer contained
|
||||
// inside the option can be passed around.
|
||||
unsafe {
|
||||
if #handlers.is_none() {
|
||||
#handlers = Some(::ext_php_rs::php::types::object::ZendObjectHandlers::init::<#name>());
|
||||
}
|
||||
|
||||
::ext_php_rs::php::types::object::ZendClassObject::<#name>::new_ptr(
|
||||
ce,
|
||||
#handlers.unwrap()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(output)
|
||||
}
|
@ -7,3 +7,5 @@ pub mod macros;
|
||||
pub mod bindings;
|
||||
pub mod functions;
|
||||
pub mod php;
|
||||
|
||||
pub use ext_php_rs_derive::ZendObjectHandler;
|
||||
|
@ -1,43 +0,0 @@
|
||||
pub use paste::paste;
|
||||
|
||||
/// Implements the [`ZendObjectOverride`] trait for the given type.
|
||||
/// Also defines the static mutable object handlers for the type.
|
||||
/// **MUST** be called in conjunction with the [`object_handlers_init`] macro.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `$class` - The type to implement the trait for.
|
||||
#[macro_export]
|
||||
macro_rules! object_override_handler {
|
||||
($class: ident) => {
|
||||
$crate::php::types::macros::paste! {
|
||||
static mut [<$class _OBJECT_HANDLERS>]: *mut $crate::php::types::object::ZendObjectHandlers = ::std::ptr::null_mut();
|
||||
|
||||
impl $crate::php::types::object::ZendObjectOverride for $class {
|
||||
extern "C" fn create_object(
|
||||
ce: *mut $crate::php::class::ClassEntry,
|
||||
) -> *mut $crate::php::types::object::ZendObject {
|
||||
unsafe {
|
||||
$crate::php::types::object::ZendClassObject::<$class>::new_ptr(ce, [<$class _OBJECT_HANDLERS>])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Initializes a types object handlers. This should be called at the start of
|
||||
/// the module startup function which is defined by the user.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `$class` - The type to initialize the handlers for.
|
||||
#[macro_export]
|
||||
macro_rules! object_handlers_init {
|
||||
($class: ident) => {{
|
||||
$crate::php::types::macros::paste! {
|
||||
let ptr = $crate::php::types::object::ZendObjectHandlers::init::<$class>();
|
||||
unsafe { [<$class _OBJECT_HANDLERS>] = ptr; };
|
||||
}
|
||||
}};
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
|
||||
pub mod array;
|
||||
pub mod long;
|
||||
pub mod macros;
|
||||
pub mod object;
|
||||
pub mod string;
|
||||
pub mod zval;
|
||||
|
Loading…
x
Reference in New Issue
Block a user