summaryrefslogtreecommitdiff
path: root/zend/object.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zend/object.cpp')
-rw-r--r--zend/object.cpp23
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);