diff options
Diffstat (limited to 'zend/object.cpp')
-rw-r--r-- | zend/object.cpp | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/zend/object.cpp b/zend/object.cpp index 08553b5..dc548cc 100644 --- a/zend/object.cpp +++ b/zend/object.cpp @@ -22,7 +22,7 @@ Object::Object(const char *name, Base *base) // does the object already have a handle? if (base->implementation()) { - // the object is already instantiated, we can assign it the this object + // the object is already instantiated, we can assign it to this object operator=(Value(base)); } else @@ -32,9 +32,12 @@ Object::Object(const char *name, Base *base) // this is a brand new object that should be allocated, the C++ instance // is already there (created by the extension) but it is not yet stored - // in PHP, find out the classname first - auto *entry = zend_fetch_class(name, ::strlen(name), 0 TSRMLS_CC); - if (!entry) throw Php::Exception(std::string("Unknown class name ") + name); + // in PHP, find out the classname first (we use the FatalError class + // here because this function is called from C++ context, and zend_error() + // would cause a longjmp() which does not clean up C++ objects created + // by the extension). + auto *entry = zend_fetch_class(name, ::strlen(name), ZEND_FETCH_CLASS_SILENT TSRMLS_CC); + if (!entry) throw FatalError(std::string("Unknown class name ") + name); // construct an implementation (this will also set the implementation // member in the base object) @@ -42,6 +45,9 @@ Object::Object(const char *name, Base *base) // now we can store it operator=(Value(base)); + + // install the object handlers + Z_OBJVAL_P(_val).handlers = ClassImpl::objectHandlers(entry); } } @@ -54,9 +60,12 @@ void Object::instantiate(const char *name) // we need the tsrm_ls variable TSRMLS_FETCH(); - // convert the name into a class_entry - auto *entry = zend_fetch_class(name, ::strlen(name), 0 TSRMLS_CC); - if (!entry) throw Php::Exception(std::string("Unknown class name ") + name); + // convert the name into a class_entry (we use the FatalError class + // here because this function is called from C++ context, and zend_error() + // would cause a longjmp() which does not clean up C++ objects created + // by the extension). + auto *entry = zend_fetch_class(name, ::strlen(name), ZEND_FETCH_CLASS_SILENT TSRMLS_CC); + if (!entry) throw FatalError(std::string("Unknown class name ") + name); // initiate the zval (which was already allocated in the base constructor) object_init_ex(_val, entry); |