summaryrefslogtreecommitdiff
path: root/src/classbase.cpp
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-04 18:21:58 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-04 18:21:58 +0100
commitc028e8f932cc4206ab8446409693fba8dfe18ffb (patch)
tree4ffe8a5d77888cff291eb7dd412bbd03e51c6f29 /src/classbase.cpp
parent200952ad4004f6ee5527598622505adbe84df8af (diff)
Php::Value and Php::Object classes can now be used to wrap around Php::Base objects
Diffstat (limited to 'src/classbase.cpp')
-rw-r--r--src/classbase.cpp138
1 files changed, 37 insertions, 101 deletions
diff --git a/src/classbase.cpp b/src/classbase.cpp
index debfa7d..f9b58d0 100644
--- a/src/classbase.cpp
+++ b/src/classbase.cpp
@@ -14,29 +14,6 @@
namespace Php {
/**
- * Function that is called to clean up space that is occupied by the object
- * @param object The object to be deallocated
- */
-static void deallocate_object(void *object TSRMLS_DC)
-{
- // allocate memory for the object
- MixedObject *obj = (MixedObject *)object;
-
- // deallocate the cpp object
- if (obj->cpp) delete obj->cpp;
-
- // get rid of the object properties
- // @todo if we enable the following two lines, segmentation
- // faults and memory corruption occurs. however, the online
- // documentation does it like this
- //zend_hash_destroy(obj->php.properties);
- //FREE_HASHTABLE(obj->php.properties);
-
- // deallocate the entire object
- efree(obj);
-}
-
-/**
* Retrieve our C++ implementation object
* @param entry
* @return ClassBase
@@ -61,94 +38,45 @@ static ClassBase *cpp_class(zend_class_entry *entry)
}
/**
- * Create an object based on a certain class entry
- * @param entry
- * @return MixedObject
- */
-static MixedObject *allocate_object(zend_class_entry *entry)
-{
- // allocate memory for the object
- MixedObject *result = (MixedObject *)emalloc(sizeof(MixedObject));
-
- // store the class entry in the newly created object
- result->php.ce = entry;
-
-#if PHP_VERSION_ID < 50399
- // the original create_object fills the initial object with the default properties,
- // we're going to do exactly the same. start with setting up a hashtable for the props
- ALLOC_HASHTABLE(result->php.properties);
-
- // initialize the hash table
- zend_hash_init(result->php.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
-
- // initialize the properties
- zend_hash_copy(result->php.properties, &entry->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval*));
-#else
- // version higher than 5.3 have an easier way to initialize
- object_properties_init(&result->php, entry);
-#endif
-
- // done
- return result;
-}
-
-/**
- * Forward declaration
- */
-static zend_object_value clone_object(zval *val TSRMLS_DC);
-
-/**
- * Store the mixed object in the PHP object cache
- * @param object The object to store
- * @param value The zend_object_value to initialize
- */
-static void store(MixedObject *object, zend_object_value *value)
-{
- // set the handlers
- value->handlers = zend_get_std_object_handlers();
-
- // we need a special handler for cloning
- value->handlers->clone_obj = clone_object;
-
- // the destructor and clone handlers are set to NULL. I dont know why, but they do not
- // seem to be necessary...
- value->handle = zend_objects_store_put(object, NULL, deallocate_object, NULL TSRMLS_CC);
-}
-
-/**
* Function that is called to create space for a cloned object
* @param val The object to be cloned
* @return zend_obejct_value The object to be created
*/
-static zend_object_value clone_object(zval *val TSRMLS_DC)
+zend_object_value ClassBase::cloneObject(zval *val TSRMLS_DC)
{
- // @todo refactoring because there is a lot of double code here
-
// retrieve the class entry linked to this object
auto *entry = zend_get_class_entry(val);
- // allocate memory for the new object
- MixedObject *new_object = allocate_object(entry);
+ // we need the C++ class meta-information object
+ ClassBase *meta = cpp_class(entry);
// retrieve the old object, which we are going to copy
MixedObject *old_object = (MixedObject *)zend_object_store_get_object(val);
+
+ // create a new base c++ object
+ auto *cpp = meta->clone(old_object->cpp);
- // we need the C++ class meta-information object
- ClassBase *meta = cpp_class(entry);
-
+ // report error on failure
+ if (!cpp) throw Php::Exception(std::string("Unable to clone ") + entry->name);
+
// the thing we're going to return
zend_object_value result;
+ // set the handlers
+ result.handlers = zend_get_std_object_handlers();
+
+ // we need a special handler for cloning
+ result.handlers->clone_obj = &ClassBase::cloneObject;
+
// store the object
- store(new_object, &result);
+ MixedObject *new_object = cpp->store(entry);
+ // store the object in the object cache
+ result.handle = cpp->handle();
+
// clone the members
zend_objects_clone_members(&new_object->php, result, &old_object->php, Z_OBJ_HANDLE_P(val));
- // finally, construct the cpp object
- // @todo call this earlier, because it could fail
- new_object->cpp = meta->clone(old_object->cpp, result);
-
// done
return result;
}
@@ -159,24 +87,32 @@ static zend_object_value clone_object(zval *val TSRMLS_DC)
* @param entry Pointer to the class information
* @return zend_object_value The newly created object
*/
-static zend_object_value create_object(zend_class_entry *entry TSRMLS_DC)
+zend_object_value ClassBase::createObject(zend_class_entry *entry TSRMLS_DC)
{
- // allocate memory for the object
- MixedObject *new_object = allocate_object(entry);
-
// we need the C++ class meta-information object
ClassBase *meta = cpp_class(entry);
+ // create a new base C++ object
+ auto *cpp = meta->construct();
+
+ // report error on failure
+ if (!cpp) throw Php::Exception(std::string("Unable to instantiate ") + entry->name);
+
// the thing we're going to return
zend_object_value result;
- // store the object
- store(new_object, &result);
+ // set the handlers
+ result.handlers = zend_get_std_object_handlers();
+
+ // we need a special handler for cloning
+ result.handlers->clone_obj = ClassBase::cloneObject;
- // finally, construct the cpp object
- // @todo call this earlier because it could fail
- new_object->cpp = meta->construct(result);
+ // store the object
+ cpp->store(entry);
+ // store the object in the object cache
+ result.handle = cpp->handle();
+
// done
return result;
}
@@ -257,7 +193,7 @@ void ClassBase::initialize(const std::string &prefix)
INIT_CLASS_ENTRY_EX(entry, _name.c_str(), _name.size(), entries());
// we need a special constructor
- entry.create_object = create_object;
+ entry.create_object = &ClassBase::createObject;
// register the class
_entry = zend_register_internal_class(&entry TSRMLS_CC);