From 75944e3e755053bc2ebe9a2a8c55575941f79a56 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Mon, 12 Jan 2015 21:54:59 +0100 Subject: Added missing executestate.h file (forgot that in previous commit), and solved issue #158, the Php::Object constructor for multiple parameters accidentally matched the call to Php::Object(name, implementation) --- include/base.h | 12 ++++++++ include/object.h | 13 +++++++-- zend/executestate.h | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 zend/executestate.h diff --git a/include/base.h b/include/base.h index f5ebed1..417aef0 100644 --- a/include/base.h +++ b/include/base.h @@ -34,6 +34,18 @@ protected: */ Base() {} + /** + * Copy constructor + * + * This copy constructor is explicitly defined to make sure that the + * copied object does not already have an implementation in the zend engine. + * Otherwise the copied object has the same object handle as the original + * object. + * + * @param base + */ + Base(const Base &base) : _impl(nullptr) {} + public: /** * Virtual destructor diff --git a/include/object.h b/include/object.h index 2e92f6a..0cdeb5c 100644 --- a/include/object.h +++ b/include/object.h @@ -64,17 +64,24 @@ public: */ Object(Base *base) : Value(base) {} + /** + * Constructor to create a new instance + * @param name Name of the class to instantiate + */ + Object(const char *name) : Value() { if (instantiate(name)) call("__construct"); } + /** * Constructor to create a new instance * - * This constructor comes in many different forms, to support all possible - * number of parameters that are passed to the constructor + * Note that it was not possible to create a constructor with signature + * Object(const char *name, Args&&... args) because that overrides the + * Object(const char *name, Base *base) constructor. * * @param name Name of the class to instantiate * @param args Optional arguments */ template - Object(const char *name, Args&&... args) : Value() { if (instantiate(name)) call("__construct", std::forward(args)...); } + Object(const char *name, Value arg0, Args&&... args) : Value() { if (instantiate(name)) call("__construct", arg0, std::forward(args)...); } /** * Destructor diff --git a/zend/executestate.h b/zend/executestate.h new file mode 100644 index 0000000..8e33b16 --- /dev/null +++ b/zend/executestate.h @@ -0,0 +1,79 @@ +/** + * ExecuteState.h + * + * Class that keeps the current execution state (this is used when a different + * script or file is eval'ed to store the execution state so that we can switch + * back to the original state. + * + * @author Emiel Bruijntjes + * @copyright 2014 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Helper class to store and restore the current opcode state + * + * When we're going to execute a set of instructions, we need to store the + * current state of the Zend engine. After the instructions have been processed, + * we can switch back to the original instructions + */ +class ExecuteState +{ +private: + /** + * All the original settings + */ + zend_op_array *_active_op_array; + zval **_return_value_ptr_ptr; + zend_op **_opline_ptr; + int _interactive; + +#ifdef ZTS + /** + * When in thread safety mode, we also keep track of the TSRM_LS var + * @var void*** + */ + void ***tsrm_ls; +#endif + +public: + /** + * Constructor + */ + ExecuteState(TSRMLS_D) + { + // store all the original stuff + _active_op_array = EG(active_op_array); + _return_value_ptr_ptr = EG(return_value_ptr_ptr); + _opline_ptr = EG(opline_ptr); + _interactive = CG(interactive); + +#ifdef ZTS + // copy tsrm_ls param + this->tsrm_ls = tsrm_ls; +#endif + } + + /** + * Destructor + */ + virtual ~ExecuteState() + { + // restore all settings + CG(interactive) = _interactive; + EG(no_extensions) = 0; + EG(opline_ptr) = _opline_ptr; + EG(active_op_array) = _active_op_array; + EG(return_value_ptr_ptr) = _return_value_ptr_ptr; + } +}; + +/** + * End of namespace + */ +} + -- cgit v1.2.3