Skip to content

Commit 7cd96a7

Browse files
committed
Design class api.
1 parent 5c22f42 commit 7cd96a7

File tree

3 files changed

+84
-15
lines changed

3 files changed

+84
-15
lines changed

examples/simple/src/lib.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use phper::zend::api::{FunctionEntries, ModuleGlobals, function_entry_end};
66
use phper::zend::compile::{InternalArgInfos, internal_arg_info_begin};
77
use phper::zend::ini::{IniEntryDefs, ini_entry_def_end};
88
use phper::zend::modules::{ModuleEntry, create_zend_module_entry};
9-
use phper::zend::types::{ExecuteData, Val, SetVal, Value};
9+
use phper::zend::types::{ExecuteData, Val, SetVal, Value, ClassEntry};
1010
use phper::{
1111
php_function, php_minit, php_minit_function, php_mshutdown, php_mshutdown_function,
1212
php_rinit_function, php_rshutdown_function,
@@ -20,7 +20,7 @@ use std::ptr::{null, null_mut};
2020
use phper::zend::exceptions::MyException;
2121
use phper::sys::{php_info_print_table_start, php_info_print_table_row, php_info_print_table_end, phper_init_class_entry};
2222

23-
static mut MY_CLASS_CE: *mut zend_class_entry = null_mut();
23+
static MY_CLASS_CE: ClassEntry = ClassEntry::new();
2424

2525
static SIMPLE_ENABLE: ModuleGlobals<bool> = ModuleGlobals::new(false);
2626
static SIMPLE_TEXT: ModuleGlobals<*const c_char> = ModuleGlobals::new(null());
@@ -35,11 +35,9 @@ static INI_ENTRIES: IniEntryDefs<3> = IniEntryDefs::new([
3535
fn m_init_simple(type_: c_int, module_number: c_int) -> bool {
3636
unsafe {
3737
zend_register_ini_entries(INI_ENTRIES.as_ptr(), module_number);
38-
}
39-
unsafe {
40-
let mut my_class_ce = phper_init_class_entry(c_str_ptr!("MyClass"), MY_CLASS_METHODS.as_ptr());
41-
MY_CLASS_CE = zend_register_internal_class(&mut my_class_ce);
42-
zend_declare_property_string(MY_CLASS_CE, c_str_ptr!("foo"), 3, c_str_ptr!("bar"), ZEND_ACC_PUBLIC as c_int);
38+
39+
MY_CLASS_CE.init(c_str_ptr!("MyClass"), &MY_CLASS_METHODS);
40+
MY_CLASS_CE.declare_property("foo", 3, ZEND_ACC_PUBLIC);
4341
}
4442
true
4543
}
@@ -66,8 +64,8 @@ fn r_shutdown_simple(type_: c_int, module_number: c_int) -> bool {
6664
fn m_info_simple(zend_module: *mut ::phper::sys::zend_module_entry) {
6765
unsafe {
6866
php_info_print_table_start();
69-
php_info_print_table_row(2, c_str_ptr!("simple.enable"), format!("{}\0", *SIMPLE_ENABLE.as_ptr()).as_ptr());
70-
php_info_print_table_row(2, c_str_ptr!("simple.text"), format!("{}\0", CStr::from_ptr((*SIMPLE_TEXT.as_ptr())).to_str().unwrap()).as_ptr());
67+
php_info_print_table_row(2, if SIMPLE_ENABLE.get() { c_str_ptr!("1") } else { c_str_ptr!("0") });
68+
php_info_print_table_row(2, c_str_ptr!("simple.text"), SIMPLE_TEXT.as_ptr());
7169
php_info_print_table_end();
7270
}
7371
}
@@ -182,14 +180,13 @@ pub fn my_class_foo(execute_data: ExecuteData) -> impl SetVal {
182180
null_mut()
183181
};
184182

185-
let foo = zend_read_property(MY_CLASS_CE, this, c_str_ptr!("foo"), 3, 1, null_mut());
183+
let foo = zend_read_property(MY_CLASS_CE.get(), this, c_str_ptr!("foo"), 3, 1, null_mut());
186184
let foo = Val::from_raw(foo);
187185
let foo = foo.as_c_str().unwrap().to_str().unwrap();
188186
Some(format!("{}{}", prefix, foo))
189187
}
190188
}
191189

192-
193190
static MODULE_ENTRY: ModuleEntry = ModuleEntry::new(create_zend_module_entry(
194191
c_str_ptr!(env!("CARGO_PKG_NAME")),
195192
c_str_ptr!(env!("CARGO_PKG_VERSION")),

phper/src/zend/api.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ impl<T: 'static> ModuleGlobals<T> {
3838
}
3939
}
4040

41+
impl<T: Copy + 'static> ModuleGlobals<T> {
42+
pub fn get(&self) -> T {
43+
self.inner.get()
44+
}
45+
}
46+
4147
unsafe impl<T: 'static> Sync for ModuleGlobals<T> {}
4248

4349
pub struct FunctionEntries<const N: usize> {

phper/src/zend/types.rs

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,57 @@
11
use crate::sys::{zend_execute_data, zval, zend_type, phper_zval_get_type, IS_STRING, IS_NULL,
2-
IS_TRUE, IS_FALSE, phper_zval_stringl, zend_throw_exception
2+
IS_TRUE, IS_FALSE, phper_zval_stringl, zend_throw_exception,
3+
zend_class_entry, phper_init_class_entry, zend_register_internal_class,
4+
zend_declare_property_stringl, zend_declare_property, IS_LONG,
35
};
46
use crate::c_str_ptr;
57
use std::ffi::CStr;
68
use std::borrow::Cow;
79
use crate::zend::exceptions::Throwable;
810
use std::ptr::{null, null_mut};
11+
use std::cell::Cell;
12+
use std::marker::PhantomData;
13+
use std::os::raw::{c_char, c_int};
14+
use crate::zend::api::FunctionEntries;
15+
use std::mem::MaybeUninit;
16+
17+
pub struct ClassEntry {
18+
inner: Cell<*mut zend_class_entry>,
19+
}
20+
21+
impl ClassEntry {
22+
pub const fn new() -> Self {
23+
Self {
24+
inner: Cell::new(null_mut()),
25+
}
26+
}
27+
28+
pub const fn as_ptr(&self) -> *mut *mut zend_class_entry {
29+
self.inner.as_ptr()
30+
}
31+
32+
pub fn get(&self) -> *mut zend_class_entry {
33+
self.inner.get()
34+
}
35+
36+
pub fn init<const N: usize>(&self, class_name: *const c_char, functions: &FunctionEntries<N>) {
37+
unsafe {
38+
let mut class_ce = phper_init_class_entry(class_name, functions.as_ptr());
39+
*self.as_ptr() = zend_register_internal_class(&mut class_ce);
40+
}
41+
}
42+
43+
pub fn declare_property(&self, name: impl AsRef<str>, value: impl SetVal, access_type: u32) {
44+
unsafe {
45+
let name = name.as_ref();
46+
let mut property: MaybeUninit<zval> = MaybeUninit::uninit();
47+
let mut property = Val::from_raw(property.as_mut_ptr());
48+
value.set_val(&mut property);
49+
zend_declare_property(self.get(), name.as_ptr().cast(), name.len(), property.as_ptr(), access_type as c_int);
50+
}
51+
}
52+
}
53+
54+
unsafe impl Sync for ClassEntry {}
955

1056
pub struct ExecuteData {
1157
raw: *mut zend_execute_data,
@@ -62,14 +108,13 @@ pub struct Val {
62108
}
63109

64110
impl Val {
65-
#[inline]
66-
pub fn from_raw(val: *mut zval) -> Self {
111+
pub const fn from_raw(val: *mut zval) -> Self {
67112
Self {
68113
raw: val,
69114
}
70115
}
71116

72-
pub fn get(&self) -> *mut zval {
117+
pub const fn as_ptr(&self) -> *mut zval {
73118
self.raw
74119
}
75120

@@ -112,6 +157,27 @@ impl SetVal for bool {
112157
}
113158
}
114159

160+
impl SetVal for i32 {
161+
fn set_val(self, val: &mut Val) {
162+
(self as i64).set_val(val)
163+
}
164+
}
165+
166+
impl SetVal for u32 {
167+
fn set_val(self, val: &mut Val) {
168+
(self as i64).set_val(val)
169+
}
170+
}
171+
172+
impl SetVal for i64 {
173+
fn set_val(self, val: &mut Val) {
174+
unsafe {
175+
(*val.as_ptr()).value.lval = self;
176+
(*val.as_ptr()).u1.type_info = IS_LONG;
177+
}
178+
}
179+
}
180+
115181
impl SetVal for &str {
116182
fn set_val(self, val: &mut Val) {
117183
unsafe {

0 commit comments

Comments
 (0)