Skip to content

Commit cf63541

Browse files
committed
provide access to return_value, function's type, filename, line number
When observing a function via observer API or zend_execute_*, these additional functions allow looking up the function's type and the filename (for user functions and eval'd code). From ExecuteData we can also retrieve the return value in a number of ways.
1 parent d747288 commit cf63541

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

phper/src/functions.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,28 @@ impl ZFunc {
647647
}
648648
}
649649

650+
/// Get the type of the function (ZEND_USER_FUNCTION, ZEND_INTERNAL_FUNCTION, etc).
651+
pub fn get_type(&self) -> u8 {
652+
unsafe { self.inner.type_ as u8 }
653+
}
654+
655+
/// For a user function or eval'd code, get the filename from op_array.
656+
pub fn get_filename(&self) -> Option<&ZStr> {
657+
unsafe {
658+
match u32::from(self.inner.type_) {
659+
ZEND_USER_FUNCTION | ZEND_EVAL_CODE => {
660+
let filename_ptr = self.inner.op_array.filename;
661+
if !filename_ptr.is_null() {
662+
ZStr::try_from_ptr(filename_ptr)
663+
} else {
664+
None
665+
}
666+
}
667+
_ => None,
668+
}
669+
}
670+
}
671+
650672
/// Get the function or method fully-qualified name.
651673
pub fn get_function_or_method_name(&self) -> ZString {
652674
unsafe {

phper/src/values.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,50 @@ impl ExecuteData {
130130
unsafe { ZFunc::from_mut_ptr(self.inner.func) }
131131
}
132132

133+
/// Gets the current opline line number if available. This represents the
134+
/// line number in the source code where the current operation is being executed.
135+
pub fn get_lineno(&self) -> Option<u32> {
136+
unsafe {
137+
match u32::from((*self.inner.func).type_) {
138+
ZEND_USER_FUNCTION | ZEND_EVAL_CODE => {
139+
let opline = self.inner.opline;
140+
if !opline.is_null() {
141+
Some((*opline).lineno as u32)
142+
} else {
143+
None
144+
}
145+
}
146+
_ => None,
147+
}
148+
}
149+
}
150+
151+
/// Gets associated return value.
152+
pub fn get_return_value(&self) -> Option<&ZVal> {
153+
unsafe {
154+
let val = self.inner.return_value;
155+
ZVal::try_from_ptr(val)
156+
}
157+
}
158+
159+
/// Gets associated return value.
160+
pub fn get_return_value_mut(&mut self) -> Option<&mut ZVal> {
161+
unsafe {
162+
let val = self.inner.return_value;
163+
ZVal::try_from_mut_ptr(val)
164+
}
165+
}
166+
167+
/// Gets associated return value pointer.
168+
pub fn get_return_value_mut_ptr(&mut self) -> *mut ZVal {
169+
self.inner.return_value as *mut ZVal
170+
}
171+
172+
/// Gets associated return value pointer.
173+
pub fn get_return_value_ptr(&self) -> *const ZVal {
174+
self.inner.return_value as *const ZVal
175+
}
176+
133177
/// Gets associated `$this` object if exists.
134178
pub fn get_this(&mut self) -> Option<&ZObj> {
135179
unsafe {

0 commit comments

Comments
 (0)