Skip to content

Commit 4a20f82

Browse files
committed
Pass the parse parameters.
1 parent 07fca95 commit 4a20f82

File tree

3 files changed

+197
-115
lines changed

3 files changed

+197
-115
lines changed

examples/simple/src/lib.rs

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -69,37 +69,15 @@ fn m_info_simple(module: &ModuleEntry) {
6969

7070
#[php_function]
7171
pub fn test_simple(execute_data: ExecuteData) -> impl SetVal {
72-
let mut a: *const c_char = null_mut();
73-
let mut a_len = 0;
74-
let mut b: *const c_char = null_mut();
75-
let mut b_len = 0;
76-
77-
unsafe {
78-
if zend_parse_parameters(
79-
execute_data.num_args() as c_int,
80-
c_str_ptr!("ss"),
81-
&mut a,
82-
&mut a_len,
83-
&mut b,
84-
&mut b_len,
85-
) != ZEND_RESULT_CODE_SUCCESS
86-
{
87-
return None;
88-
}
89-
90-
Some(format!(
72+
execute_data.parse_parameters::<(&str, &str)>().map(|(a, b)| {
73+
format!(
9174
"a = {}, a_len = {}, b = {}, b_len = {}",
92-
CStr::from_ptr(a).to_str().unwrap(),
93-
a_len,
94-
CStr::from_ptr(b).to_str().unwrap(),
95-
b_len,
96-
))
97-
}
98-
}
99-
100-
#[php_function]
101-
pub fn test_parse(execute_data: ExecuteData) -> impl SetVal {
102-
execute_data.parse_parameters::<bool>()
75+
a,
76+
a.len(),
77+
b,
78+
b.len(),
79+
)
80+
})
10381
}
10482

10583
static ARG_INFO_TEST_SIMPLE: MultiInternalArgInfo<3> = MultiInternalArgInfo::new([

examples/simple/tests/confirm_compiled.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,3 @@
77
var_dump(get_extension_funcs('simple'));
88
var_dump(test_simple("aaa", "bbb"));
99
var_dump((new MyClass())->foo("foo-"));
10-
11-
var_dump(test_parse(false));

phper/src/zend/types.rs

Lines changed: 189 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -90,110 +90,216 @@ impl ExecuteData {
9090
}
9191

9292
pub trait ParseParameter: Sized {
93-
fn parse(arg_num: usize) -> Option<Self>;
94-
}
93+
fn spec() -> Cow<'static, str>;
94+
95+
fn num_parameters() -> usize;
96+
97+
fn parameters() -> Vec<*mut c_void>;
98+
99+
fn from_parameters(parameters: &[*mut c_void]) -> Option<Self>;
95100

96-
impl ParseParameter for bool {
97101
fn parse(num_args: usize) -> Option<Self> {
98-
let mut b = false;
99-
if unsafe { zend_parse_parameters(num_args as c_int, c_str_ptr!("b"), &mut b) == ZEND_RESULT_CODE_SUCCESS } {
100-
Some(b)
102+
let mut parameters = Self::parameters();
103+
if zend_parse_fixed_parameters(num_args, &Self::spec(), &parameters) {
104+
Self::from_parameters(&parameters)
101105
} else {
102106
None
103107
}
104-
// if (c_str_ptr!("b"), &mut b as *const _).call_zend_parse_parameters(arg_num) {
105-
// if zend_parse_fixed_parameters(num_args, "b\0", parameters) {
106-
// } else {
107-
// None
108-
// }
109108
}
110109
}
111110

112-
// impl<A: ParseParameter, B: ParseParameter> ParseParameter for (A, B) {
113-
// fn spec() -> Cow<'static, str> {
114-
// let mut s= String::new();
115-
// s.push_str(&<A>::spec());
116-
// s.push_str(&<B>::spec());
117-
// Cow::Owned(s)
118-
// }
119-
//
120-
// fn push_parameters(parameters: &mut Vec<*const c_void>) {
121-
// unimplemented!()
122-
// }
123-
//
124-
// fn parse(arg_num: i32) -> Option<Self> {
125-
// let a = null_mut();
126-
// let b = null_mut();
127-
//
128-
// #[repr(C)]
129-
// struct Parameters(*mut c_void, *mut c_void);
130-
//
131-
// let parameters = Parameters(a, b);
132-
//
133-
// let result = unsafe {
134-
// zend_parse_parameters(arg_num, (&*Self::spec()).as_ptr().cast(), parameters) == ZEND_RESULT_CODE_SUCCESS
135-
// };
136-
// }
137-
// }
138-
139-
fn zend_parse_fixed_parameters(num_args: usize, type_spec: &str, parameters: [*mut c_void; 10]) -> bool {
140-
assert!(num_args <= 10);
141-
assert!(type_spec.ends_with('\0'));
142-
143-
let mut fixed_parameters = [null_mut(); 20];
144-
145-
let mut i = 0;
146-
for c in type_spec.chars() {
147-
match c {
148-
's' => {
149-
fixed_parameters[i] = parameters[i];
150-
i += 1;
151-
}
152-
'*' | '+' | '|' | '/' | '!' | '\0' => {}
153-
_ => {
154-
fixed_parameters[i] = parameters[i];
155-
}
156-
}
157-
i += 1;
111+
impl ParseParameter for bool {
112+
#[inline]
113+
fn spec() -> Cow<'static, str> {
114+
Cow::Borrowed("b")
158115
}
159116

160-
unsafe {
161-
zend_parse_parameters(num_args as c_int, type_spec.as_ptr().cast(), fixed_parameters) == ZEND_RESULT_CODE_SUCCESS
117+
#[inline]
118+
fn num_parameters() -> usize {
119+
1
120+
}
121+
122+
#[inline]
123+
fn parameters() -> Vec<*mut c_void> {
124+
vec![Box::into_raw(Box::new(false)).cast()]
125+
}
126+
127+
fn from_parameters(parameters: &[*mut c_void]) -> Option<Self> {
128+
let b = unsafe { Box::from_raw(parameters[0] as *mut bool) };
129+
Some(*b)
162130
}
163131
}
164132

165-
trait CallZendParseParameters {
166-
fn call_zend_parse_parameters(self, num_args: c_int) -> bool;
133+
impl ParseParameter for i64 {
134+
#[inline]
135+
fn spec() -> Cow<'static, str> {
136+
Cow::Borrowed("l")
137+
}
138+
139+
#[inline]
140+
fn num_parameters() -> usize {
141+
1
142+
}
143+
144+
#[inline]
145+
fn parameters() -> Vec<*mut c_void> {
146+
vec![Box::into_raw(Box::new(0i64)).cast()]
147+
}
148+
149+
fn from_parameters(parameters: &[*mut c_void]) -> Option<Self> {
150+
let i = unsafe { Box::from_raw(parameters[0] as *mut i64) };
151+
Some(*i)
152+
}
167153
}
168154

169-
macro_rules! generate_impl_call_zend_parse_parameters {
170-
{ $(($n:tt, $T:ident)),*} => {
171-
impl<$($T,)*> CallZendParseParameters for (*const c_char, $(*const $T,)*) {
155+
impl ParseParameter for f64 {
156+
#[inline]
157+
fn spec() -> Cow<'static, str> {
158+
Cow::Borrowed("d")
159+
}
160+
161+
#[inline]
162+
fn num_parameters() -> usize {
163+
1
164+
}
165+
166+
#[inline]
167+
fn parameters() -> Vec<*mut c_void> {
168+
vec![Box::into_raw(Box::new(0f64)).cast()]
169+
}
170+
171+
fn from_parameters(parameters: &[*mut c_void]) -> Option<Self> {
172+
let i = unsafe { Box::from_raw(parameters[0] as *mut f64) };
173+
Some(*i)
174+
}
175+
}
176+
177+
impl ParseParameter for &str {
178+
#[inline]
179+
fn spec() -> Cow<'static, str> {
180+
Cow::Borrowed("s")
181+
}
182+
183+
#[inline]
184+
fn num_parameters() -> usize {
185+
2
186+
}
187+
188+
#[inline]
189+
fn parameters() -> Vec<*mut c_void> {
190+
vec![Box::into_raw(Box::new(null_mut::<c_char>())).cast(), Box::into_raw(Box::new(0u32)).cast()]
191+
}
192+
193+
fn from_parameters(parameters: &[*mut c_void]) -> Option<Self> {
194+
unsafe {
195+
let ptr = Box::from_raw(parameters[0] as *mut *mut c_char);
196+
let _len = Box::from_raw(parameters[1] as *mut c_int);
197+
CStr::from_ptr(*ptr).to_str().ok()
198+
}
199+
}
200+
}
201+
202+
macro_rules! impl_parse_parameter_for_tuple {
203+
{ $(($t:ident,$T:ident)),* } => {
204+
impl<$($T: ParseParameter,)*> ParseParameter for ($($T,)*) {
205+
fn spec() -> Cow<'static, str> {
206+
let mut s= String::new();
207+
$(s.push_str(&<$T>::spec());)*
208+
Cow::Owned(s)
209+
}
210+
172211
#[inline]
173-
fn call_zend_parse_parameters(self, num_args: i32) -> bool {
174-
unsafe {
175-
zend_parse_parameters(num_args, self.0, $(self.$n,)*) == ZEND_RESULT_CODE_SUCCESS
176-
}
212+
fn num_parameters() -> usize {
213+
0 $( + <$T>::num_parameters())*
214+
}
215+
216+
fn parameters() -> Vec<*mut c_void> {
217+
let mut parameters = Vec::new();
218+
$(parameters.extend_from_slice(&<$T>::parameters());)*
219+
parameters
220+
}
221+
222+
fn from_parameters(parameters: &[*mut c_void]) -> Option<Self> {
223+
let mut i = 0;
224+
225+
$(let $t = {
226+
let j = i;
227+
i += <$T>::num_parameters();
228+
match <$T>::from_parameters(&parameters[j..i]) {
229+
Some(item) => item,
230+
None => return None,
231+
}
232+
};)*
233+
234+
Some(($($t,)*))
177235
}
178236
}
179237
};
180238
}
181239

182-
generate_impl_call_zend_parse_parameters!();
183-
generate_impl_call_zend_parse_parameters!((1, A));
184-
generate_impl_call_zend_parse_parameters!((1, A), (2, B));
185-
generate_impl_call_zend_parse_parameters!((1, A), (2, B), (3, C));
186-
generate_impl_call_zend_parse_parameters!((1, A), (2, B), (3, C), (4, D));
187-
generate_impl_call_zend_parse_parameters!((1, A), (2, B), (3, C), (4, D), (5, E));
188-
generate_impl_call_zend_parse_parameters!((1, A), (2, B), (3, C), (4, D), (5, E), (6, F));
189-
generate_impl_call_zend_parse_parameters!((1, A), (2, B), (3, C), (4, D), (5, E), (6, F), (7, G));
190-
generate_impl_call_zend_parse_parameters!((1, A), (2, B), (3, C), (4, D), (5, E), (6, F), (7, G), (8, H));
191-
generate_impl_call_zend_parse_parameters!((1, A), (2, B), (3, C), (4, D), (5, E), (6, F), (7, G), (8, H), (9, I));
192-
generate_impl_call_zend_parse_parameters!((1, A), (2, B), (3, C), (4, D), (5, E), (6, F), (7, G), (8, H), (9, I), (10, J));
193-
generate_impl_call_zend_parse_parameters!((1, A), (2, B), (3, C), (4, D), (5, E), (6, F), (7, G), (8, H), (9, I), (10, J), (11, K));
194-
generate_impl_call_zend_parse_parameters!((1, A), (2, B), (3, C), (4, D), (5, E), (6, F), (7, G), (8, H), (9, I), (10, J), (11, K), (12, L));
195-
generate_impl_call_zend_parse_parameters!((1, A), (2, B), (3, C), (4, D), (5, E), (6, F), (7, G), (8, H), (9, I), (10, J), (11, K), (12, L), (13, M));
196-
generate_impl_call_zend_parse_parameters!((1, A), (2, B), (3, C), (4, D), (5, E), (6, F), (7, G), (8, H), (9, I), (10, J), (11, K), (12, L), (13, M), (14, N));
240+
impl_parse_parameter_for_tuple!((a, A));
241+
impl_parse_parameter_for_tuple!((a, A), (b, B));
242+
impl_parse_parameter_for_tuple!((a, A), (b, B), (c, C));
243+
impl_parse_parameter_for_tuple!((a, A), (b, B), (c, C), (d, D));
244+
impl_parse_parameter_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E));
245+
impl_parse_parameter_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F));
246+
impl_parse_parameter_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G));
247+
impl_parse_parameter_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G), (h, H));
248+
impl_parse_parameter_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G), (h, H), (i, I));
249+
impl_parse_parameter_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G), (h, H), (i, I), (j, J));
250+
251+
fn zend_parse_fixed_parameters(num_args: usize, type_spec: &str, parameters: &[*mut c_void]) -> bool {
252+
assert!(parameters.len() <= 20);
253+
let type_spec = format!("{}\0", type_spec);
254+
255+
let p0 = parameters.get(0).map(Clone::clone).unwrap_or(null_mut());
256+
let p1 = parameters.get(1).map(Clone::clone).unwrap_or(null_mut());
257+
let p2 = parameters.get(2).map(Clone::clone).unwrap_or(null_mut());
258+
let p3 = parameters.get(3).map(Clone::clone).unwrap_or(null_mut());
259+
let p4 = parameters.get(4).map(Clone::clone).unwrap_or(null_mut());
260+
let p5 = parameters.get(5).map(Clone::clone).unwrap_or(null_mut());
261+
let p6 = parameters.get(6).map(Clone::clone).unwrap_or(null_mut());
262+
let p7 = parameters.get(7).map(Clone::clone).unwrap_or(null_mut());
263+
let p8 = parameters.get(8).map(Clone::clone).unwrap_or(null_mut());
264+
let p9 = parameters.get(9).map(Clone::clone).unwrap_or(null_mut());
265+
let p10 = parameters.get(10).map(Clone::clone).unwrap_or(null_mut());
266+
let p11 = parameters.get(11).map(Clone::clone).unwrap_or(null_mut());
267+
let p12 = parameters.get(12).map(Clone::clone).unwrap_or(null_mut());
268+
let p13 = parameters.get(13).map(Clone::clone).unwrap_or(null_mut());
269+
let p14 = parameters.get(14).map(Clone::clone).unwrap_or(null_mut());
270+
let p15 = parameters.get(15).map(Clone::clone).unwrap_or(null_mut());
271+
let p16 = parameters.get(16).map(Clone::clone).unwrap_or(null_mut());
272+
let p17 = parameters.get(17).map(Clone::clone).unwrap_or(null_mut());
273+
let p18 = parameters.get(18).map(Clone::clone).unwrap_or(null_mut());
274+
let p19 = parameters.get(19).map(Clone::clone).unwrap_or(null_mut());
275+
276+
unsafe {
277+
zend_parse_parameters(
278+
num_args as c_int,
279+
type_spec.as_ptr().cast(),
280+
p0 ,
281+
p1 ,
282+
p2 ,
283+
p3 ,
284+
p4 ,
285+
p5 ,
286+
p6 ,
287+
p7 ,
288+
p8 ,
289+
p9 ,
290+
p10,
291+
p11,
292+
p12,
293+
p13,
294+
p14,
295+
p15,
296+
p16,
297+
p17,
298+
p18,
299+
p19,
300+
) == ZEND_RESULT_CODE_SUCCESS
301+
}
302+
}
197303

198304
#[repr(u32)]
199305
pub enum ValType {

0 commit comments

Comments
 (0)