-
Notifications
You must be signed in to change notification settings - Fork 76
Add wrapper for zend_exec_stringl with exception handling #67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use crate::bindings::zend_eval_stringl; | ||
use crate::errors::{Error, Result}; | ||
use crate::php::globals::ExecutorGlobals; | ||
use crate::php::types::zval::Zval; | ||
use std::ffi::CString; | ||
use std::rc::Rc; | ||
|
||
pub fn eval(code: &str) -> Result<Zval> { | ||
let mut ret = Zval::new(); | ||
let code = CString::new(code)?; | ||
|
||
let result = unsafe { | ||
zend_eval_stringl( | ||
code.as_ptr(), | ||
code.as_bytes().len() as u64, | ||
&mut ret, | ||
CString::new("")?.as_ptr(), | ||
) | ||
}; | ||
|
||
if result < 0 { | ||
Err(Error::CompileFailed) | ||
} else if let Some(exception) = ExecutorGlobals::take_exception() { | ||
Err(Error::UncaughtException(Rc::new(exception))) | ||
} else { | ||
Ok(ret) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
use crate::bindings::{_zend_executor_globals, ext_php_rs_executor_globals}; | ||
|
||
use super::types::array::ZendHashTable; | ||
use super::types::{array::ZendHashTable, object::ZendObject}; | ||
|
||
/// Stores global variables used in the PHP executor. | ||
pub type ExecutorGlobals = _zend_executor_globals; | ||
|
@@ -16,6 +16,14 @@ impl ExecutorGlobals { | |
.expect("Static executor globals were invalid") | ||
} | ||
|
||
fn get_mut() -> &'static mut Self { | ||
// SAFETY: PHP executor globals are statically declared therefore should never | ||
// return an invalid pointer. | ||
// TODO: Should this be syncronized? | ||
unsafe { ext_php_rs_executor_globals().as_mut() } | ||
.expect("Static executor globals were invalid") | ||
Comment on lines
+23
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kept this private because I don't know in general if this is thread safe. As I understand it, the |
||
} | ||
|
||
/// Attempts to retrieve the global class hash table. | ||
pub fn class_table(&self) -> Option<ZendHashTable> { | ||
if self.class_table.is_null() { | ||
|
@@ -24,4 +32,17 @@ impl ExecutorGlobals { | |
|
||
unsafe { ZendHashTable::from_ptr(self.class_table, false) }.ok() | ||
} | ||
|
||
pub fn take_exception() -> Option<Box<ZendObject>> { | ||
let globals = Self::get_mut(); | ||
|
||
let mut exception_ptr = std::ptr::null_mut(); | ||
std::mem::swap(&mut exception_ptr, &mut globals.exception); | ||
|
||
if !exception_ptr.is_null() { | ||
Some(unsafe { Box::from_raw(exception_ptr) }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I understand the php source code, we're responsible for freeing it if we take it. |
||
} else { | ||
None | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,3 +16,4 @@ pub mod globals; | |
pub mod module; | ||
pub mod pack; | ||
pub mod types; | ||
pub mod eval; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, what's the benefit of having ordering on an error enum?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comparison.