Skip to content

Commit f6a3674

Browse files
committed
Fix declare string property.
1 parent 45ec8d1 commit f6a3674

File tree

7 files changed

+104
-60
lines changed

7 files changed

+104
-60
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ jobs:
4848
override: true
4949
components: rustfmt, clippy
5050

51-
- name: Install Cargo make
52-
uses: actions-rs/cargo@v1
53-
with:
54-
command: install
55-
args: cargo-make
51+
# - name: Install Cargo make
52+
# uses: actions-rs/cargo@v1
53+
# with:
54+
# command: install
55+
# args: cargo-make
5656

5757
- name: Cargo fmt
5858
uses: actions-rs/cargo@v1

examples/simple/src/lib.rs

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,20 @@ use phper::{
44
php_rshutdown_function,
55
sys::{
66
php_info_print_table_end, php_info_print_table_row, php_info_print_table_start,
7-
zend_function_entry, zend_read_property, OnUpdateBool, OnUpdateString, PHP_INI_SYSTEM,
8-
ZEND_ACC_PUBLIC,
7+
zend_function_entry, OnUpdateBool, OnUpdateString, PHP_INI_SYSTEM, ZEND_ACC_PUBLIC,
98
},
109
zend::{
1110
api::{FunctionEntries, ModuleGlobals},
1211
compile::{create_zend_arg_info, MultiInternalArgInfo},
1312
ini::IniEntries,
1413
modules::{create_zend_module_entry, ModuleArgs, ModuleEntry},
15-
types::{ClassEntry, ExecuteData, SetVal, Val, Value},
14+
types::{ClassEntry, ExecuteData, SetVal, Value},
1615
},
1716
zend_get_module,
1817
};
1918
use std::{
20-
os::raw::c_char,
21-
ptr::{null, null_mut},
19+
os::raw::{c_char, c_int},
20+
ptr::null,
2221
};
2322

2423
static MY_CLASS_CE: ClassEntry = ClassEntry::new();
@@ -35,7 +34,7 @@ static INI_ENTRIES: IniEntries<2> = IniEntries::new([
3534
fn m_init_simple(args: ModuleArgs) -> bool {
3635
args.register_ini_entries(&INI_ENTRIES);
3736
MY_CLASS_CE.init(c_str_ptr!("MyClass"), &MY_CLASS_METHODS);
38-
MY_CLASS_CE.declare_property("foo", "foo", ZEND_ACC_PUBLIC);
37+
MY_CLASS_CE.declare_property("name", "world", ZEND_ACC_PUBLIC as c_int);
3938
true
4039
}
4140

@@ -80,7 +79,7 @@ fn m_info_simple(module: &ModuleEntry) {
8079
}
8180

8281
#[php_function]
83-
pub fn test_simple(execute_data: ExecuteData) -> impl SetVal {
82+
pub fn test_simple(execute_data: &mut ExecuteData) -> impl SetVal {
8483
execute_data
8584
.parse_parameters::<(&str, &str)>()
8685
.map(|(a, b)| {
@@ -110,28 +109,23 @@ static FUNCTION_ENTRIES: FunctionEntries<1> = FunctionEntries::new([zend_functio
110109
flags: 0,
111110
}]);
112111

113-
static ARG_INFO_MY_CLASS_FOO: MultiInternalArgInfo<1> =
112+
static ARG_INFO_MY_CLASS_HELLO: MultiInternalArgInfo<1> =
114113
MultiInternalArgInfo::new([create_zend_arg_info(c_str_ptr!("prefix"), false)], false);
115114

116115
static MY_CLASS_METHODS: FunctionEntries<1> = FunctionEntries::new([zend_function_entry {
117-
fname: c_str_ptr!("foo"),
118-
handler: Some(php_fn!(my_class_foo)),
119-
arg_info: ARG_INFO_MY_CLASS_FOO.as_ptr(),
116+
fname: c_str_ptr!("hello"),
117+
handler: Some(php_fn!(my_class_hello)),
118+
arg_info: ARG_INFO_MY_CLASS_HELLO.as_ptr(),
120119
num_args: 1,
121120
flags: 0,
122121
}]);
123122

124123
#[php_function]
125-
pub fn my_class_foo(execute_data: ExecuteData) -> impl SetVal {
124+
pub fn my_class_hello(execute_data: &mut ExecuteData) -> impl SetVal {
126125
execute_data.parse_parameters::<&str>().map(|prefix| {
127126
let this = execute_data.get_this();
128-
assert_ne!(this as *mut _, null_mut());
129-
130-
let foo = unsafe {
131-
zend_read_property(MY_CLASS_CE.get(), this, c_str_ptr!("foo"), 3, 1, null_mut())
132-
};
133-
let foo = Val::from_raw(foo);
134-
let value = foo.try_into_value().unwrap();
127+
let val = MY_CLASS_CE.read_property(this, "name");
128+
let value = val.try_into_value().unwrap();
135129

136130
if let Value::CStr(foo) = value {
137131
Some(format!("{}{}", prefix, foo.to_str().unwrap()))

examples/simple/tests/php/test.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
assert_eq(get_extension_funcs('simple'), ["test_simple"]);
88
assert_eq(test_simple("aaa", "bbb"), "a = aaa, a_len = 3, b = bbb, b_len = 3");
9-
assert_eq((new MyClass())->foo("bar-"), "bar-foo");
9+
assert_eq((new MyClass())->hello("hello, "), "hello, world");
1010

1111
function assert_eq($left, $right) {
1212
if ($left !== $right) {

phper-macros/src/inner.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,11 @@ pub(crate) fn php_function(_attr: TokenStream, input: TokenStream) -> TokenStrea
9696
fn internal(#inputs) #ret {
9797
#body
9898
}
99-
let internal: fn(::phper::zend::types::ExecuteData) -> _ = internal;
100-
let value = internal(::phper::zend::types::ExecuteData::from_raw(execute_data));
101-
::phper::zend::types::SetVal::set_val(value, &mut ::phper::zend::types::Val::from_raw(return_value));
99+
let internal: fn(&mut ::phper::zend::types::ExecuteData) -> _ = internal;
100+
unsafe {
101+
let value = internal(::phper::zend::types::ExecuteData::from_mut(execute_data));
102+
::phper::zend::types::SetVal::set_val(value, ::phper::zend::types::Val::from_mut(return_value));
103+
}
102104
}
103105
};
104106

phper-sys/php_wrapper.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@ void phper_zval_stringl(zval *return_value, const char *s, size_t len) {
2828

2929
char *phper_z_strval_p(const zval *v) {
3030
return Z_STRVAL_P(v);
31-
}
31+
}
32+
33+
zval *phper_get_this(zend_execute_data *execute_data) {
34+
return getThis();
35+
}

phper-sys/php_wrapper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ void phper_zval_string(zval *return_value, const char *s);
1313
zend_uchar phper_zval_get_type(const zval* pz);
1414
void phper_zval_stringl(zval *return_value, const char *s, size_t len);
1515
char *phper_z_strval_p(const zval *v);
16+
zval *phper_get_this(zend_execute_data *execute_data);
1617

1718
#endif //PHPER_PHP_WRAPPER_H

phper/src/zend/types.rs

Lines changed: 74 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
use crate::{
22
c_str_ptr,
33
sys::{
4-
self, phper_init_class_entry, phper_z_strval_p, phper_zval_get_type, phper_zval_stringl,
5-
zend_class_entry, zend_declare_property, zend_execute_data, zend_parse_parameters,
6-
zend_register_internal_class, zend_throw_exception, zval, IS_FALSE, IS_LONG, IS_NULL,
7-
IS_TRUE, ZEND_RESULT_CODE_SUCCESS,
4+
self, phper_get_this, phper_init_class_entry, phper_z_strval_p, phper_zval_get_type,
5+
phper_zval_stringl, zend_class_entry, zend_declare_property_stringl, zend_execute_data,
6+
zend_parse_parameters, zend_read_property, zend_register_internal_class,
7+
zend_throw_exception, zval, IS_FALSE, IS_LONG, IS_NULL, IS_TRUE, ZEND_RESULT_CODE_SUCCESS,
88
},
99
zend::{api::FunctionEntries, exceptions::Throwable},
1010
};
1111
use std::{
1212
borrow::Cow,
1313
cell::Cell,
1414
ffi::{c_void, CStr},
15-
mem::MaybeUninit,
1615
os::raw::{c_char, c_int},
1716
ptr::null_mut,
1817
};
@@ -43,42 +42,85 @@ impl ClassEntry {
4342
}
4443
}
4544

46-
pub fn declare_property(&self, name: impl AsRef<str>, value: impl SetVal, access_type: u32) {
45+
pub fn declare_property(
46+
&self,
47+
name: impl AsRef<str>,
48+
value: impl DeclareProperty,
49+
access_type: c_int,
50+
) -> bool {
4751
unsafe {
4852
let name = name.as_ref();
49-
let mut property: MaybeUninit<zval> = MaybeUninit::uninit();
50-
let mut property = Val::from_raw(property.as_mut_ptr());
51-
value.set_val(&mut property);
52-
zend_declare_property(
53+
value.declare_property(self.get(), name, access_type) == ZEND_RESULT_CODE_SUCCESS
54+
}
55+
}
56+
57+
pub fn read_property(&self, this: *mut zval, name: impl AsRef<str>) -> &mut Val {
58+
let name = name.as_ref();
59+
unsafe {
60+
let v = zend_read_property(
5361
self.get(),
62+
this,
5463
name.as_ptr().cast(),
5564
name.len(),
56-
property.as_ptr(),
57-
access_type as c_int,
65+
1,
66+
null_mut(),
5867
);
68+
Val::from_mut(v)
5969
}
6070
}
6171
}
6272

6373
unsafe impl Sync for ClassEntry {}
6474

75+
pub trait DeclareProperty {
76+
unsafe fn declare_property(
77+
self,
78+
ce: *mut zend_class_entry,
79+
name: &str,
80+
access_type: c_int,
81+
) -> c_int;
82+
}
83+
84+
impl DeclareProperty for &str {
85+
unsafe fn declare_property(
86+
self,
87+
ce: *mut zend_class_entry,
88+
name: &str,
89+
access_type: i32,
90+
) -> c_int {
91+
zend_declare_property_stringl(
92+
ce,
93+
name.as_ptr().cast(),
94+
name.len(),
95+
self.as_ptr().cast(),
96+
self.len(),
97+
access_type,
98+
)
99+
}
100+
}
101+
102+
#[repr(transparent)]
65103
pub struct ExecuteData {
66-
raw: *mut zend_execute_data,
104+
inner: zend_execute_data,
67105
}
68106

69107
impl ExecuteData {
70-
pub fn from_raw(execute_data: *mut zend_execute_data) -> Self {
71-
Self { raw: execute_data }
108+
pub unsafe fn from_mut<'a>(ptr: *mut zend_execute_data) -> &'a mut Self {
109+
&mut *(ptr as *mut Self)
110+
}
111+
112+
pub fn as_mut(&mut self) -> *mut zend_execute_data {
113+
&mut self.inner
72114
}
73115

74116
#[inline]
75117
pub fn num_args(&self) -> usize {
76-
unsafe { (*self.raw).This.u2.num_args as usize }
118+
unsafe { self.inner.This.u2.num_args as usize }
77119
}
78120

79121
#[inline]
80-
pub fn get_this(&self) -> &mut zval {
81-
unsafe { &mut (*self.raw).This }
122+
pub fn get_this(&mut self) -> *mut zval {
123+
unsafe { phper_get_this(&mut self.inner) }
82124
}
83125

84126
pub fn parse_parameters<T: ParseParameter>(&self) -> Option<T> {
@@ -309,25 +351,26 @@ fn zend_parse_fixed_parameters(
309351
b == ZEND_RESULT_CODE_SUCCESS
310352
}
311353

354+
#[repr(transparent)]
312355
pub struct Val {
313-
raw: *mut zval,
356+
inner: zval,
314357
}
315358

316359
impl Val {
317-
pub const fn from_raw(val: *mut zval) -> Self {
318-
Self { raw: val }
360+
pub unsafe fn from_mut<'a>(ptr: *mut zval) -> &'a mut Self {
361+
&mut *(ptr as *mut Self)
319362
}
320363

321-
pub const fn as_ptr(&self) -> *mut zval {
322-
self.raw
364+
pub fn as_mut(&mut self) -> *mut zval {
365+
&mut self.inner
323366
}
324367

325-
pub fn try_into_value<'a>(self) -> crate::Result<Value<'a>> {
326-
Value::from_zval(self.raw)
368+
pub fn try_into_value<'a>(&self) -> crate::Result<Value<'a>> {
369+
Value::from_ptr(&self.inner)
327370
}
328371

329372
unsafe fn type_info(&mut self) -> &mut u32 {
330-
&mut (*self.raw).u1.type_info
373+
&mut self.inner.u1.type_info
331374
}
332375
}
333376

@@ -366,24 +409,24 @@ impl SetVal for u32 {
366409
impl SetVal for i64 {
367410
fn set_val(self, val: &mut Val) {
368411
unsafe {
369-
(*val.as_ptr()).value.lval = self;
370-
(*val.as_ptr()).u1.type_info = IS_LONG;
412+
(*val.as_mut()).value.lval = self;
413+
(*val.as_mut()).u1.type_info = IS_LONG;
371414
}
372415
}
373416
}
374417

375418
impl SetVal for &str {
376419
fn set_val(self, val: &mut Val) {
377420
unsafe {
378-
phper_zval_stringl(val.raw, self.as_ptr().cast(), self.len());
421+
phper_zval_stringl(val.as_mut(), self.as_ptr().cast(), self.len());
379422
}
380423
}
381424
}
382425

383426
impl SetVal for String {
384427
fn set_val(self, val: &mut Val) {
385428
unsafe {
386-
phper_zval_stringl(val.raw, self.as_ptr().cast(), self.len());
429+
phper_zval_stringl(val.as_mut(), self.as_ptr().cast(), self.len());
387430
}
388431
}
389432
}
@@ -422,7 +465,7 @@ pub enum Value<'a> {
422465
}
423466

424467
impl<'a> Value<'a> {
425-
pub fn from_zval(v: *const zval) -> crate::Result<Self> {
468+
pub fn from_ptr(v: *const zval) -> crate::Result<Self> {
426469
unsafe {
427470
match phper_zval_get_type(v) as u32 {
428471
sys::IS_NULL => Ok(Self::Null),

0 commit comments

Comments
 (0)