summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile20
-rw-r--r--config/config.cpp28
-rw-r--r--include/exception.h37
-rw-r--r--phpcpp.h26
-rw-r--r--src/callable.cpp2
-rw-r--r--src/classimpl.cpp33
-rw-r--r--src/exception.cpp34
-rw-r--r--src/extensionimpl.cpp4
-rw-r--r--src/extensionimpl.h2
-rw-r--r--src/includes.h6
-rw-r--r--src/origexception.cpp35
-rw-r--r--src/origexception.h112
-rw-r--r--src/value.cpp2
13 files changed, 138 insertions, 203 deletions
diff --git a/Makefile b/Makefile
index 6bac3de..9a66157 100644
--- a/Makefile
+++ b/Makefile
@@ -140,24 +140,13 @@ OBJECTS = $(SOURCES:%.cpp=%.o)
PHP_OBJECTS = $(PHP_SOURCES:%.cpp=%.o)
HHVM_OBJECTS = $(HHVM_SOURCES:%.cpp=%.o)
-#
-# Configuration program
-#
-# During installation, a configuration utility will be installed. It is
-# compiled with the following instructions
-#
-
-CONFIG_UTILITY = ./create_config
-CONFIG_SOURCES = $(wildcard config/*.cpp)
-CONFIG_FLAGS = `php-config --includes` -o
-
#
# End of the variables section. Here starts the list of instructions and
# dependencies that are used by the compiler.
#
-all: ${PHP_LIBRARY} ${CONFIG_UTILITY}
+all: ${PHP_LIBRARY}
${PHP_LIBRARY}: ${OBJECTS} ${PHP_OBJECTS}
${LINKER} ${PHP_LINKER_FLAGS} -o $@ ${OBJECTS} ${PHP_OBJECTS}
@@ -165,11 +154,8 @@ ${PHP_LIBRARY}: ${OBJECTS} ${PHP_OBJECTS}
${HHVM_LIBRARY}: ${OBJECTS} ${HHVM_OBJECTS}
${LINKER} ${HHVM_LINKER_FLAGS} -o $@ ${OBJECTS} ${HHVM_OBJECTS}
-${CONFIG_UTILITY}:
- ${COMPILER} ${CONFIG_FLAGS} $@ ${CONFIG_SOURCES}
-
clean:
- ${RM} ${OBJECTS} ${PHP_OBJECTS} ${HHVM_OBJECTS} ${PHP_LIBRARY} ${HHVM_LIBRARY} ${CONFIG_UTILITY}
+ ${RM} ${OBJECTS} ${PHP_OBJECTS} ${HHVM_OBJECTS} ${PHP_LIBRARY} ${HHVM_LIBRARY}
${OBJECTS}:
${COMPILER} ${PHP_COMPILER_FLAGS} -o $@ ${@:%.o=%.cpp}
@@ -186,10 +172,8 @@ install:
${CP} include/*.h ${INSTALL_HEADERS}/phpcpp
if [ -e ${PHP_LIBRARY} ]; then ${CP} ${PHP_LIBRARY} ${INSTALL_LIB}; fi
if [ -e ${HHVM_LIBRARY} ]; then ${CP} ${HHVM_LIBRARY} ${INSTALL_LIB}; fi
- ${CONFIG_UTILITY} > ${INSTALL_HEADERS}/phpcpp/config.h
test:
mkdir -p ./tests/include/zts/phpcpp
- ${CONFIG_UTILITY} > ./tests/include/zts/phpcpp/config.h
cd tests && ./test.sh -p "${PHP_BIN}"
diff --git a/config/config.cpp b/config/config.cpp
deleted file mode 100644
index 2fcd5ad..0000000
--- a/config/config.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * Config.cpp
- *
- * Simple programs that creates the config file for PHP-CPP. PHP-CPP needs
- * a different config file when it is installed on a system with multi-threaded
- * PHP, and on a system with single threaded PHP.
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2014 Copernica BV
- */
-#include <iostream>
-#include <php_config.h>
-
-/**
- * Main procedure
- * @return int
- */
-int main()
-{
-#ifdef ZTS
- // also define ZTS in the config file
- std::cout << "#define ZTS" << std::endl;
-#endif
-
- // done
- return 0;
-}
-
diff --git a/include/exception.h b/include/exception.h
index dd38035..671df9e 100644
--- a/include/exception.h
+++ b/include/exception.h
@@ -30,42 +30,51 @@ private:
*/
int _code;
+ /**
+ * Has this exception been processed by native C++ code?
+ * @var bool
+ */
+ bool _processed = false;
+
public:
/**
* Constructor
* @param &string
*/
- Exception(const std::string &message, int code = 0) : std::exception(), _message(message), _code(code)
- {
- }
+ Exception(const std::string &message, int code = 0) : std::exception(), _message(message), _code(code) {}
/**
* Destructor
*/
- virtual ~Exception() throw()
+ virtual ~Exception() throw() {}
+
+ /**
+ * Overridden what method
+ * @return const char *
+ */
+ virtual const char *what() const noexcept override
{
+ return _message.c_str();
}
/**
* Returns the message of the exception.
* @return &string
*/
- std::string &message() throw()
+ const std::string &message() const throw()
{
return _message;
}
/**
- * Process the exception
- *
- * This method is called only from within the PHP-CPP library,
- * and will turn the exception into a PHP exception
- *
- * @param tsrm_ls
- *
- * @internal
+ * Is this a native exception (one that was thrown from C++ code)
+ * @return bool
*/
- virtual void process(TSRMLS_D);
+ virtual bool native() const
+ {
+ // yes, it is native
+ return true;
+ }
};
/**
diff --git a/phpcpp.h b/phpcpp.h
index a07d1ac..90ef218 100644
--- a/phpcpp.h
+++ b/phpcpp.h
@@ -23,32 +23,6 @@
#include <map>
/**
- * Include PHP config
- */
-#include <phpcpp/config.h>
-
-/**
- * Is ZTS enabled?
- */
-#ifdef ZTS
-
- // enable TSRM
-# define TSRMLS_C tsrm_ls
-# define TSRMLS_CC ,tsrm_ls
-# define TSRMLS_D void ***tsrm_ls
-# define TSRMLS_DC ,void ***tsrm_ls
-
-#else
-
- // disable TSRM
-# define TSRMLS_C
-# define TSRMLS_CC
-# define TSRMLS_D
-# define TSRMLS_DC
-
-#endif
-
-/**
* Include all headers files that are related to this library
*/
#include <phpcpp/exception.h>
diff --git a/src/callable.cpp b/src/callable.cpp
index d1b94c5..737b85b 100644
--- a/src/callable.cpp
+++ b/src/callable.cpp
@@ -46,7 +46,7 @@ static void invoke_callable(INTERNAL_FUNCTION_PARAMETERS)
catch (Exception &exception)
{
// process the exception
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
}
}
diff --git a/src/classimpl.cpp b/src/classimpl.cpp
index 8e062d4..d63956a 100644
--- a/src/classimpl.cpp
+++ b/src/classimpl.cpp
@@ -114,7 +114,7 @@ void ClassImpl::callMethod(INTERNAL_FUNCTION_PARAMETERS)
catch (Exception &exception)
{
// process the exception
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
}
}
@@ -155,12 +155,11 @@ void ClassImpl::callInvoke(INTERNAL_FUNCTION_PARAMETERS)
{
// because of the two-step nature, we are going to report the error ourselves
zend_error(E_ERROR, "Function name must be a string");
-
}
catch (Exception &exception)
{
// process the exception
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
}
}
@@ -419,7 +418,7 @@ int ClassImpl::compare(zval *val1, zval *val2 TSRMLS_DC)
{
// a Php::Exception was thrown by the extension __compare function,
// pass this on to user space
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
// what shall we return here...
return 1;
@@ -492,7 +491,7 @@ int ClassImpl::cast(zval *val, zval *retval, int type TSRMLS_DC)
catch (Exception &exception)
{
// pass on the exception to php userspace
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
// done
return FAILURE;
@@ -577,7 +576,7 @@ int ClassImpl::countElements(zval *object, long *count TSRMLS_DC)
catch (Exception &exception)
{
// process the exception
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
// unreachable
return FAILURE;
@@ -640,7 +639,7 @@ zval *ClassImpl::readDimension(zval *object, zval *offset, int type TSRMLS_DC)
catch (Exception &exception)
{
// process the exception (send it to user space)
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
// unreachable
return Value(nullptr).detach();
@@ -685,7 +684,7 @@ void ClassImpl::writeDimension(zval *object, zval *offset, zval *value TSRMLS_DC
catch (Exception &exception)
{
// process the exception (send it to user space
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
}
}
else
@@ -734,7 +733,7 @@ int ClassImpl::hasDimension(zval *object, zval *member, int check_empty TSRMLS_D
catch (Exception &exception)
{
// process the exception (send it to user space)
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
// unreachable
return false;
@@ -777,7 +776,7 @@ void ClassImpl::unsetDimension(zval *object, zval *member TSRMLS_DC)
catch (Exception &exception)
{
// process the exception (send it to user space)
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
}
}
else
@@ -894,7 +893,7 @@ zval *ClassImpl::readProperty(zval *object, zval *name, int type, const zend_lit
{
// user threw an exception in its magic method
// implementation, send it to user space
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
// unreachable
return Value(nullptr).detach();
@@ -971,7 +970,7 @@ void ClassImpl::writeProperty(zval *object, zval *name, zval *value, const zend_
{
// user threw an exception in its magic method
// implementation, send it to user space
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
}
}
@@ -1052,7 +1051,7 @@ int ClassImpl::hasProperty(zval *object, zval *name, int has_set_exists, const z
{
// user threw an exception in its magic method
// implementation, send it to user space
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
// unreachable
return false;
@@ -1113,7 +1112,7 @@ void ClassImpl::unsetProperty(zval *object, zval *member, const zend_literal *ke
{
// user threw an exception in its magic method
// implementation, send it to user space
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
}
}
@@ -1147,7 +1146,7 @@ void ClassImpl::destructObject(zend_object *object, zend_object_handle handle TS
{
// a regular Php::Exception was thrown by the extension, pass it on
// to PHP user space
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
}
}
@@ -1162,7 +1161,7 @@ void ClassImpl::freeObject(zend_object *object TSRMLS_DC)
ObjectImpl *obj = ObjectImpl::find(object);
// no longer need it
- obj->destruct(TSRMLS_CC);
+ obj->destruct(TSRMLS_C);
}
/**
@@ -1228,7 +1227,7 @@ zend_object_iterator *ClassImpl::getIterator(zend_class_entry *entry, zval *obje
{
// user threw an exception in its method
// implementation, send it to user space
- exception.process(TSRMLS_C);
+ process(exception TSRMLS_CC);
// unreachable
return nullptr;
diff --git a/src/exception.cpp b/src/exception.cpp
deleted file mode 100644
index 810a73c..0000000
--- a/src/exception.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Exception.cpp
- *
- * Implementation for the exception class
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2014 Copernica BV
- */
-#include "includes.h"
-
-/**
- * Set up namespace
- */
-namespace Php {
-
-/**
- * Process the exception
- *
- * This method is called only from within the PHP-CPP library,
- * and will turn the exception into a PHP exception
- *
- * @param tsrm_ls
- */
-void Exception::process(TSRMLS_D)
-{
- // an exception originally thrown by C++ should be passed on to PHP
- zend_throw_exception(zend_exception_get_default(TSRMLS_C), (char*)message().c_str(), 0 TSRMLS_CC);
-}
-
-/**
- * End namespace
- */
-}
-
diff --git a/src/extensionimpl.cpp b/src/extensionimpl.cpp
index 0197757..9562362 100644
--- a/src/extensionimpl.cpp
+++ b/src/extensionimpl.cpp
@@ -115,7 +115,7 @@ int ExtensionImpl::onStartup(int type, int module_number TSRMLS_DC)
auto *extension = find(module_number TSRMLS_CC);
// initialize the extension
- extension->initialize(TSRMLS_CC);
+ extension->initialize(TSRMLS_C);
// is the callback registered?
if (extension->_onStartup) extension->_onStartup();
@@ -289,7 +289,7 @@ void ExtensionImpl::initialize(TSRMLS_D)
_data->apply([TSRMLS_C](const std::string &prefix, ClassBase &c) {
// forward to implementation class
- c.implementation()->initialize(&c, prefix TSRMLS_C);
+ c.implementation()->initialize(&c, prefix TSRMLS_CC);
});
}
diff --git a/src/extensionimpl.h b/src/extensionimpl.h
index 8c9ae58..cc37354 100644
--- a/src/extensionimpl.h
+++ b/src/extensionimpl.h
@@ -166,7 +166,7 @@ private:
* Initialize the namespace after it was registered
* @param tsrm_ls
*/
- void initialize(TSRMLS_DC);
+ void initialize(TSRMLS_D);
/**
* Function that is called when the extension initializes
diff --git a/src/includes.h b/src/includes.h
index f547eb2..0019244 100644
--- a/src/includes.h
+++ b/src/includes.h
@@ -23,9 +23,9 @@
// for debug
#include <iostream>
-//#define ZTS
-//#define THREAD_T pthread_t
-//#define MUTEX_T pthread_mutex_t *
+#define ZTS
+#define THREAD_T pthread_t
+#define MUTEX_T pthread_mutex_t *
/**
* PHP includes
diff --git a/src/origexception.cpp b/src/origexception.cpp
deleted file mode 100644
index f64d696..0000000
--- a/src/origexception.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Implementation of the exception that was originally thrown by PHP
- * code or the zend engine, and that could or could not be picked
- * up by C++ code
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
- */
-#include "includes.h"
-
-/**
- * Set up namespace
- */
-namespace Php {
-
-/**
- * Destructor
- */
-OrigException::~OrigException() noexcept
-{
- // skip if the exception was restored
- if (_restored) return;
-
- // we need the tsrm_ls var
- TSRMLS_FETCH();
-
- // clean up the exception, because it was handled in C++ code
- zend_clear_exception(TSRMLS_C);
-}
-
-/**
- * End of namespace
- */
-}
-
diff --git a/src/origexception.h b/src/origexception.h
index 5cbb0e1..775e412 100644
--- a/src/origexception.h
+++ b/src/origexception.h
@@ -18,62 +18,128 @@ namespace Php {
*/
class OrigException : public Value, public Exception
{
-private:
+private:
/**
- * Has the exception been restored by the C++ code so that it can be dealt by PHP?
- * @var boolean
+ * 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***
*/
- bool _restored = false;
+ TSRMLS_D;
+#endif
public:
/**
* Constructor
- * @param zval
+ * @param val
*/
- OrigException(struct _zval_struct *zval) :
- Value(zval), Exception("OrigException") {}
+ 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"), _restored(exception._restored) {}
+ 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"), _restored(exception._restored)
+ Value(std::move(exception)), Exception("OrigException"), _handled(exception._handled)
{
- // set other exception to restored so that it wont
- // do anything on destruction
- exception._restored = true;
+ // 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();
+ 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);
+ }
/**
- * Process the exception
- *
- * This will restore the exception so that it can be further processed
- * in PHP code
- *
- * @param tsrm_ls
- * @internal
+ * This is _not_ a native exception, it was thrown by a PHP script
+ * @return bool
*/
- virtual void process(TSRMLS_D) override
+ virtual bool native() const override
{
- // mark exception as restored
- _restored = true;
+ 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
*/
}
diff --git a/src/value.cpp b/src/value.cpp
index 9addb8c..2ca1585 100644
--- a/src/value.cpp
+++ b/src/value.cpp
@@ -1257,7 +1257,7 @@ static Value do_exec(zval **object, zval *method, int argc, zval ***params)
{
// was an exception thrown inside the function? In that case we throw a C++ new exception
// to give the C++ code the chance to catch it
- if (oldException != EG(exception) && EG(exception)) throw OrigException(EG(exception));
+ if (oldException != EG(exception) && EG(exception)) throw OrigException(EG(exception) TSRMLS_CC);
// no (additional) exception was thrown
return retval ? Value(retval) : nullptr;