Skip to content

Commit 7c484a0

Browse files
Refactor ZendHashTable and Zval (#76)
* Call zval destructor when changing zval type and dropping * Remove zval return from array insert functions #73 The functions actually returned references to the new zval value, so there's not much point in returning. * Remove `ZendHashTable` wrapper Replaced by returning references to the actual hashtable, and having a new type `OwnedHashTable` when creating a new hashtable. * Remove pointless `drop` field from `OwnedHashTable` * Added `Values` iterator for Zend hashtable * Change iterators to double ended and exact size
1 parent ff231ec commit 7c484a0

File tree

11 files changed

+562
-528
lines changed

11 files changed

+562
-528
lines changed

build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,4 +313,6 @@ const ALLOWED_BINDINGS: &[&str] = &[
313313
"_ZEND_TYPE_NULLABLE_BIT",
314314
"ts_rsrc_id",
315315
"_ZEND_TYPE_NAME_BIT",
316+
"zval_ptr_dtor",
317+
"zend_refcounted_h",
316318
];

example/skel/src/lib.rs

Lines changed: 7 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,25 @@
11
mod allocator;
22

3-
use allocator::PhpAllocator;
43
use ext_php_rs::{
4+
parse_args,
55
php::{
6+
args::Arg,
7+
enums::DataType,
68
exceptions::PhpException,
9+
execution_data::ExecutionData,
10+
function::FunctionBuilder,
711
types::{
12+
array::OwnedHashTable,
813
callable::Callable,
914
closure::Closure,
1015
object::{ClassObject, ClassRef},
16+
zval::{FromZval, IntoZval, Zval},
1117
},
1218
},
1319
php_class,
1420
prelude::*,
1521
};
1622

17-
// #[php_function]
18-
// pub fn hello_world() -> String {
19-
// let call = Callable::try_from_name("strpos").unwrap();
20-
21-
// eprintln!("im callin");
22-
// let val = call.try_call(vec![&"hello world", &"w"]);
23-
// dbg!(val);
24-
// "Ok".into()
25-
// }
26-
27-
// #[php_const]
28-
// const SKEL_TEST_CONST: &str = "Test constant";
29-
// #[php_const]
30-
// const SKEL_TEST_LONG_CONST: i32 = 1234;
31-
32-
// #[php_function(optional = "z")]
33-
// pub fn skeleton_version(x: ZendHashTable, y: f64, z: Option<f64>) -> String {
34-
// dbg!(x, y, z);
35-
// "Hello".into()
36-
// }
37-
38-
// #[php_function(optional = "z")]
39-
// pub fn skeleton_array(
40-
// arr: ZendHashTable,
41-
// x: i32,
42-
// y: f64,
43-
// z: Option<f64>,
44-
// ) -> Result<ZendHashTable, String> {
45-
// for (k, x, y) in arr.iter() {
46-
// println!("{:?} {:?} {:?}", k, x, y.string());
47-
// }
48-
49-
// dbg!(x, y, z);
50-
51-
// let mut new = ZendHashTable::new();
52-
// new.insert("Hello", &"World")
53-
// .map_err(|_| "Couldn't insert into hashtable")?;
54-
// Ok(new)
55-
// }
56-
57-
// #[php_function(optional = "i", defaults(i = 5))]
58-
// pub fn test_array(i: i32, b: Option<i32>) -> Vec<i32> {
59-
// dbg!(i, b);
60-
// vec![1, 2, 3, 4]
61-
// }
62-
63-
// #[php_function(optional = "offset", defaults(offset = 0))]
64-
// pub fn rust_strpos(haystack: &str, needle: &str, offset: i64) -> Option<usize> {
65-
// let haystack = haystack.chars().skip(offset as usize).collect::<String>();
66-
// haystack.find(needle)
67-
// }
68-
69-
// #[php_function]
70-
// pub fn example_exception() -> Result<i32, &'static str> {
71-
// Err("Bad here")
72-
// }
73-
74-
// #[php_function]
75-
// pub fn skel_unpack<'a>(
76-
// mut arr: HashMap<String, String>,
77-
// ) -> Result<HashMap<String, String>, PhpException<'a>> {
78-
// arr.insert("hello".into(), "not world".into());
79-
// Ok(arr)
80-
// }
81-
82-
// #[php_function]
83-
// pub fn test_extern() -> i32 {
84-
// // let y = unsafe { strpos("hello", "e", None) };
85-
// // dbg!(y);
86-
// // let x = unsafe { test_func() };
87-
// // dbg!(x.try_call(vec![]));
88-
// 0
89-
// }
90-
91-
// #[php_function]
92-
// pub fn test_lifetimes<'a>() -> ZendHashTable<'a> {
93-
// ZendHashTable::try_from(&HashMap::<String, String>::new()).unwrap()
94-
// }
95-
96-
#[php_function]
97-
pub fn test_str(input: &str) -> &str {
98-
input
99-
}
100-
101-
// #[no_mangle]
102-
// pub extern "C" fn php_module_info(_module: *mut ModuleEntry) {
103-
// info_table_start!();
104-
// info_table_row!("skeleton extension", "enabled");
105-
// info_table_end!();
106-
// }
107-
108-
// #[php_class(name = "Redis\\Exception\\RedisClientException")]
109-
// #[extends(ClassEntry::exception())]
110-
// #[derive(Default)]
111-
// struct RedisException;
112-
113-
// #[php_function]
114-
// pub fn test_exception() -> Result<i32, PhpException<'static>> {
115-
// Err(PhpException::from_class::<RedisException>(
116-
// "Hello world".into(),
117-
// ))
118-
// }
119-
120-
// #[global_allocator]
121-
// static GLOBAL: PhpAllocator = PhpAllocator::new();
122-
12323
#[php_class]
12424
#[property(test = 0)]
12525
#[property(another = "Hello world")]

example/skel/test.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
<?php
22

3-
include 'vendor/autoload.php';
3+
test_zval(['hello' => 'world']);
4+
//include 'vendor/autoload.php';
45

5-
$ext = new ReflectionExtension('skel');
6+
//$ext = new ReflectionExtension('skel');
67

7-
dd($ext);
8+
//dd($ext);
89

9-
$x = fn_once();
10-
$x();
11-
$x();
10+
//$x = fn_once();
11+
//$x();
12+
//$x();
1213

13-
// $x = get_closure();
14+
//// $x = get_closure();
1415

15-
// var_dump($x(5));
16+
//// var_dump($x(5));

src/php/enums.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,13 @@ impl TryFrom<ZvalTypeFlags> for DataType {
107107
}
108108
}
109109

110-
impl TryFrom<u32> for DataType {
111-
type Error = Error;
112-
110+
impl From<u32> for DataType {
113111
#[allow(clippy::bad_bit_mask)]
114-
fn try_from(value: u32) -> Result<Self> {
112+
fn from(value: u32) -> Self {
115113
macro_rules! contains {
116114
($c: ident, $t: ident) => {
117115
if (value & $c) == $c {
118-
return Ok(DataType::$t);
116+
return DataType::$t;
119117
}
120118
};
121119
}
@@ -134,12 +132,12 @@ impl TryFrom<u32> for DataType {
134132
contains!(IS_NULL, Null);
135133

136134
if (value & IS_OBJECT) == IS_OBJECT {
137-
return Ok(DataType::Object(None));
135+
return DataType::Object(None);
138136
}
139137

140138
contains!(IS_UNDEF, Undef);
141139

142-
Err(Error::UnknownDatatype(value))
140+
DataType::Mixed
143141
}
144142
}
145143

src/php/globals.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::bindings::{_zend_executor_globals, ext_php_rs_executor_globals};
44

5-
use super::types::array::ZendHashTable;
5+
use super::types::array::HashTable;
66

77
/// Stores global variables used in the PHP executor.
88
pub type ExecutorGlobals = _zend_executor_globals;
@@ -17,11 +17,7 @@ impl ExecutorGlobals {
1717
}
1818

1919
/// Attempts to retrieve the global class hash table.
20-
pub fn class_table(&self) -> Option<ZendHashTable> {
21-
if self.class_table.is_null() {
22-
return None;
23-
}
24-
25-
unsafe { ZendHashTable::from_ptr(self.class_table, false) }.ok()
20+
pub fn class_table(&self) -> Option<&HashTable> {
21+
unsafe { self.class_table.as_ref() }
2622
}
2723
}

0 commit comments

Comments
 (0)