Comments (11)
There's a discord channel that is more appropriate for these kind of lengthy discussions: https://discord.com/channels/115233111977099271/829877152048349266
from ext-php-rs.
Yeah, inheritance doesn't work ATM...
from ext-php-rs.
i don't think this is related to inheritance, the construct
function above will call parent constructor if it's called from the ce constructor ( assuming the ce refers to a class that is in PHP, no ext-php-rs as it doesn't support calling parent constructors ).
however, exceptions are different from normal classes, they need more context ( file, line, trace ), as i said, throwing and catching works, zend will make sure to construct the exception correctly, but it is slow, we need to look at how zend constructs an exception, and basically do the same, so that PhpException
wont' be just holding a reference to ce
and message
in the future, but rather a zend object, if you call new(msg, 0, ce)
it will construct that class immediately itself without throwing it, and only throws it when .throw()
is called.
this will allow us to be able to construct ext-php-rs exceptions without throwing them.
this is something that a lot of PHP libraries do, to give you an example:
while throwing immediately from forSending()
works, and can be implemented in ext-php-rs, it is not the desired behavior, because in PSL those exceptions don't get thrown when constructed, they get sent over the event loop via a suspension (
https://github.com/azjezz/psl/blob/b239bb7f8b8feb52908ad6b82ab153b6ff8b6111/src/Psl/Channel/Internal/BoundedChannelState.php#L84-L99 ), which is later suspended and throws ( https://github.com/azjezz/psl/blob/2.2.x/src/Psl/Channel/Internal/BoundedSender.php#L42-L50 )
from ext-php-rs.
correction: the construct
function above will probably fail if Foo
class doesn't define a construct but it's parent Bar
has one, we can do something like this to retrieve the ctor ( rusty-pseudo code ):
fn get_constructor() -> option {
constructor = none;
if ce.constructor == null {
traits = ce.traits;
for trait in traits {
if trait.has_constructor() {
constructor = trait.get_constructor();
break;
}
}
if constructor.is_none() {
if ce.parent != null {
// we do the same for the parent
return get_constructor(ce.parent);
}
}
} else {
constructor = some(ce.constructor);
}
constructor
}
from ext-php-rs.
none of the exception properties weren't initialized, the exception will always not have a backtrace
I think the reason why there's no backtrace is that you might be trying to construct an exception outside of a VM stack frame (when EG(current_execute_data) == null
).
If that's the case, then this is expected since no VM stack frame => no trace.
The function that creates your exception instance needs to be called from PHP (at least that's my understanding).
from ext-php-rs.
no, that's not the issue, if there's no stack frame, we would get an error.
see: https://heap.space/xref/php-src/Zend/zend_exceptions.c?r=45e224cf#205
we are missing something else that i still can't figure out :)
from ext-php-rs.
You would have an error if the exception is thrown without a stack frame, not when constructing the exception object, see https://heap.space/xref/php-src/Zend/zend_exceptions.c?r=45e224cf#244.
from ext-php-rs.
throwing it doesn't result in an error, if you try the code above an call do throw from_bar()
in PHP, it would throw the exception, but with no trace.
from ext-php-rs.
throwing it doesn't result in an error, if you try the code above an call do throw from_bar() in PHP, it would throw the exception, but with no trace.
Mmm okay... have you tried to assert that ExecutorGlobals::get().current_execute_data
is not a null pointer at the time you create the exception instance?
from ext-php-rs.
no, but i don't think that would change anything, as in my test script, the file looks exactly like this:
<?php
function foo() {
return Psl\Channel\Exception\ClosedChannelException::forSending();
}
function bar() {
throw foo();
}
function baz() {
bar();
}
baz();
meaning it is not not possible for another exception to be present.
from ext-php-rs.
for anyone reading this thread, until this issue is resolved, here's how you can create your own exceptions:
use ext_php_rs::convert::IntoZvalDyn;
use ext_php_rs::error::Result;
use ext_php_rs::ffi;
use ext_php_rs::types::Zval;
use ext_php_rs::zend::ClassEntry;
pub unsafe fn make_exception(
class: Option<&'static ClassEntry>,
arguments: Vec<&dyn IntoZvalDyn>,
) -> Result<Zval> {
let class = class.unwrap();
let len = arguments.len();
let arguments = arguments
.into_iter()
.map(|val| val.as_zval(false))
.collect::<Result<Vec<_>>>()?
.into_boxed_slice();
let class_ptr = class as *const _ as *mut _;
let constructor_ptr = class.constructor;
let object = class.__bindgen_anon_2.create_object.unwrap()(class_ptr);
ffi::zend_call_known_function(
constructor_ptr,
object,
class_ptr,
std::ptr::null_mut(),
len as _,
arguments.as_ptr() as _,
std::ptr::null_mut(),
);
let object = object
.as_mut()
.expect("error: failed to allocate memory for object");
let mut result = Zval::new();
result.set_object(object);
Ok(result)
}
Note: this is not 100% guaranteed to work, if you found an issues with it, let us know :)
let exception = unsafe { make_exception(MY_EXCEPTION_CE, vec![&message]).unwrap() };
from ext-php-rs.
Related Issues (20)
- how to get all methods of a php object? HOT 1
- Database driver usecase HOT 2
- Unable to install cargo-php HOT 4
- Static property and method HOT 2
- Err: Attempted to access uninitialized class object
- Error: Failed to copy extension from target directory to extension directory
- Feature: Add ability to build PHP as a fallback when the system library is not found
- Build error on OpenSUSE ` invalid conversion between vector type '__m128i' HOT 1
- Build failure with 0.10.3 on aarch64 HOT 3
- How to exchange datetime HOT 4
- Memory corruption when running module tests
- Performance: There seems to be a runtime related overhead with using ext-php-rs extensions in PHP HOT 11
- Stub generation of optional arguments doesn't set default value to NULL
- Module and PHP versions need to match HOT 1
- Iterator from Rust
- Can't not install cargo php under winrdows HOT 1
- Slower Than C HOT 4
- Undefined symbols while building HOT 2
- How to expose PHP's memory manager in Rust? HOT 1
- Unable to install on clean Ubuntu 22.04 docker HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ext-php-rs.