diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-04-06 21:53:24 +0200 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-04-06 21:53:24 +0200 |
commit | 35fd3ccbeb4def71b4d8a59dfbb5c31201b099b9 (patch) | |
tree | 915223360aed4743aa6127fde4836aa413a260e5 /zend/origexception.h | |
parent | da4710512865e6816585ac4ab8edab2fa125e2d8 (diff) |
renamed src directory to zend directory, disabled TSRM debug code
Diffstat (limited to 'zend/origexception.h')
-rw-r--r-- | zend/origexception.h | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/zend/origexception.h b/zend/origexception.h new file mode 100644 index 0000000..775e412 --- /dev/null +++ b/zend/origexception.h @@ -0,0 +1,145 @@ +/** + * OrigException.h + * + * Class that wraps around an exception that was thrown by PHP code, + * and that could - but not necessarily has to - be caught by C++ + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class OrigException : public Value, public Exception +{ +private: + /** + * Is this a an exception that was caught by extension C++ code. + * + * When the object is initially created, we assume that it will be caught + * by C++ code. If it later turns out that the PHP-CPP can catch this + * exception after the extension C++ code ran, the variable is set back + * to false. + * + * @var bool + */ + bool _handled = true; + +#ifdef ZTS + /** + * When we run in multi-thread mode, we store the thread handle + * @var void*** + */ + TSRMLS_D; +#endif + +public: + /** + * Constructor + * @param val + */ + OrigException(zval *val TSRMLS_DC) : + Value(val), Exception("OrigException") + { +#ifdef ZTS + // copy tsrm_ls + this->TSRMLS_C = TSRMLS_C; +#endif + } + + /** + * Copy constructor + * @param exception + */ + OrigException(const OrigException &exception) : + Value(exception), Exception("OrigException"), _handled(exception._handled) + { +#ifdef ZTS + // copy tsrm_ls + TSRMLS_C = exception.TSRMLS_C; +#endif + } + + /** + * Move constructor + * @param exception + */ + OrigException(OrigException &&exception) : + Value(std::move(exception)), Exception("OrigException"), _handled(exception._handled) + { + // set other exception to handled so that it wont do anything on destruction + exception._handled = true; + +#ifdef ZTS + // copy tsrm_ls + TSRMLS_C = exception.TSRMLS_C; +#endif + } + + /** + * Destructor + */ + virtual ~OrigException() throw() + { + // if the exception was not handled by C++ code, we're not going to do anything + // and the exception stays active + if (!_handled) return; + + // the exception was handled, so we should clean it up + zend_clear_exception(TSRMLS_C); + } + + /** + * This is _not_ a native exception, it was thrown by a PHP script + * @return bool + */ + virtual bool native() const override + { + return false; + } + + /** + * Reactivate the exception + */ + void reactivate() + { + // it was not handled by extension C++ code + _handled = false; + } +}; + +/** + * Global function to process an exception + * @param exception + * @param tsrm_ls + */ +inline void process(Exception &exception TSRMLS_DC) +{ + // is this a native exception? + if (exception.native()) + { + // the exception is native, call the zend throw method + zend_throw_exception(zend_exception_get_default(TSRMLS_C), (char *)exception.what(), 0 TSRMLS_CC); + } + else + { + // this is not a native exception, so it was originally thrown by a + // php script, and then not caught by the c++ of the extensiont, we are + // going to tell to the exception that it is still active + OrigException &orig = static_cast<OrigException&>(exception); + + // reactive the exception + orig.reactivate(); + } +} + +/** + * End of namespace + */ +} |