summaryrefslogtreecommitdiff
path: root/src/classbase.cpp
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-02 11:33:53 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-02 11:33:53 +0100
commit52fe0c39457421e075959179ee6b64a20b96f0d9 (patch)
treee6dd000114d104bf6286d74682feb694b3cb97a3 /src/classbase.cpp
parentfa02aa127d2c4261d15123829e44f6d997444abc (diff)
types are not a C++11 class, introduced FixedValue class that can not change type, and implemented both Object and Array to make use of that type, implemented - but not yet tested - Base::value() method
Diffstat (limited to 'src/classbase.cpp')
-rw-r--r--src/classbase.cpp53
1 files changed, 31 insertions, 22 deletions
diff --git a/src/classbase.cpp b/src/classbase.cpp
index 134164d..39c8790 100644
--- a/src/classbase.cpp
+++ b/src/classbase.cpp
@@ -62,11 +62,15 @@ static zend_object_value create_object(zend_class_entry *type TSRMLS_DC)
// retrieve the classinfo object
#if PHP_VERSION_ID >= 50400
- ClassBase *info = (ClassBase *)base->info.user.doc_comment;
+ const char *comment = base->info.user.doc_comment;
#else
- ClassBase *info = *((ClassBase **)base->doc_comment);
+ const char *comment = base->doc_comment;
#endif
+ // the first byte of the comment is an empty string (null character), but
+ // the next bytes contain a pointer to the ClassInfo class
+ ClassBase *info = *((ClassBase **)(comment + 1));
+
// store the class
object->php.ce = type;
@@ -76,6 +80,7 @@ static zend_object_value create_object(zend_class_entry *type TSRMLS_DC)
// initialize the hash table
zend_hash_init(object->php.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
+
// initialize the properties
#if PHP_VERSION_ID < 50399
@@ -108,6 +113,11 @@ ClassBase::~ClassBase()
{
// destruct the entries
if (_entries) delete[] _entries;
+
+ // php 5.3 deallocated the doc_comment by iself
+#if PHP_VERSION_ID >= 50400
+ if (_comment) free(_comment);
+#endif
}
/**
@@ -176,30 +186,29 @@ void ClassBase::initialize(const std::string &prefix)
// register the class
_entry = zend_register_internal_class(&entry TSRMLS_CC);
-
+
+ // allocate doc comment to contain an empty string + a hidden pointer
+ if (!_comment)
+ {
+ // allocate now
+ _comment = (char *)malloc(1 + sizeof(ClassBase *));
+
+ // empty string on first position
+ _comment[0] = '\0';
+
+ // this pointer has to be copied to temporary pointer, as &this causes compiler error
+ ClassBase *base = this;
+
+ // copy the 'this' pointer to the doc-comment
+ memcpy(_comment+1, &base, sizeof(ClassBase *));
+ }
+
// store pointer to the class in the unused doc_comment member
#if PHP_VERSION_ID >= 50400
- _entry->info.user.doc_comment = (const char *)this;
+ _entry->info.user.doc_comment = _comment;
#else
- /**
- * PHP 5.3 will free the doc_comment pointer if it
- * is not NULL, which will result in the classinfo
- * object being freed without being destructed
- * properly, leading to segfaults when the destruct
- * is called at a later stage (during module_shutdown).
- *
- * To prevent this we create an extra pointer that
- * points to our this pointer. We do *not* free this
- * pointer ourselves, because PHP does this. This
- * way it does not free the classinfo.
- */
- char **wrapper = (char**)malloc(sizeof(char**));
-
- // have the wrapper point to us
- *wrapper = (char *)this;
-
// and store the wrapper inside the comment
- _entry->doc_comment = (char *)wrapper;
+ _entry->doc_comment = _comment;
#endif
// set access types flags for class