summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-06 21:18:45 +0200
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-06 21:18:45 +0200
commitda4710512865e6816585ac4ab8edab2fa125e2d8 (patch)
tree2d2ad42235032db4160231d221babd6cb91f6371
parente8b7f9a5f80c0f296d05403a84a5259cb48f9329 (diff)
the exception.h header file no longer depends on the zend engine header files. TSRM macros are no longer used in any of the public PHPCPP header files so there is no more need for the phpcpp/config.h header file nor the config-create script
-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;