summaryrefslogtreecommitdiff
path: root/src/classinfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/classinfo.cpp')
-rw-r--r--src/classinfo.cpp153
1 files changed, 130 insertions, 23 deletions
diff --git a/src/classinfo.cpp b/src/classinfo.cpp
index 760df5c..7de7522 100644
--- a/src/classinfo.cpp
+++ b/src/classinfo.cpp
@@ -13,41 +13,147 @@
namespace Php {
/**
- * Function that is called by the Zend engine every time that a function gets called
+ * Structure that combines a C++ object with a zend object
+ */
+struct MixedObject
+{
+ zend_object php;
+ Base *cpp;
+};
+
+/**
+ * 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
+ zend_hash_destroy(obj->php.properties);
+ FREE_HASHTABLE(obj->php.properties);
+
+ // deallocate the entire object
+ efree(obj);
+}
+
+/**
+ * Function that is called to create space for a cloned object
+ * @param object The object to be cloned
+ * @param clone The address that should become the clone
+ */
+static void clone_object(void *object, void **clone TSRMLS_DC)
+{
+ std::cout << "clone_object" << std::endl;
+
+ // @todo implementation
+}
+
+/**
+ * Function that is called when an instance of the class needs to be created.
+ * This function will create the C++ class, and the PHP object
+ * @param type Pointer to the class
+ */
+static zend_object_value create_object(zend_class_entry *type TSRMLS_DC)
+{
+ // allocate memory for the object
+ MixedObject *object = (MixedObject *)emalloc(sizeof(MixedObject));
+
+ // retrieve the classinfo object
+ _ClassInfo *info = (_ClassInfo *)type->info.user.doc_comment;
+
+ // construct the cpp object
+ object->cpp = info->construct();
+
+ // store the class
+ object->php.ce = type;
+
+ // 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(object->php.properties);
+
+ // initialize the hash table
+ zend_hash_init(object->php.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
+
+ // initialize the properties
+ object_properties_init(&(object->php), type);
+
+ // the thing we're going to return
+ zend_object_value result;
+
+ // use default object handlers
+ result.handlers = zend_get_std_object_handlers();
+
+ // put the object in the storage, and assign a method for deallocating and cloning
+ result.handle = zend_objects_store_put(object, NULL, deallocate_object, clone_object TSRMLS_CC);
+
+ // done
+ return result;
+}
+
+/**
+ * Function that is called by the Zend engine every time the constructor gets called
* @param ht
* @param return_value
* @param return_value_ptr
* @param this_ptr
* @param return_value_used
* @param tsrm_ls
- * @return integer
*/
-void invoke_method(INTERNAL_FUNCTION_PARAMETERS)
+static void invoke_constructor(INTERNAL_FUNCTION_PARAMETERS)
{
- std::cout << "invoke method" << std::endl;
-
- return;
-
- // find the function name
- const char *name = get_active_function_name(TSRMLS_C);
-
- // uncover the hidden pointer inside the function name
- Function *function = HiddenPointer<Function>(name);
-
- // wrap the return value
- Value result(return_value, true);
+ // get the mixed object
+ MixedObject *obj = (MixedObject *)zend_object_store_get_object(this_ptr TSRMLS_CC);
// construct parameters
Parameters params(ZEND_NUM_ARGS());
- // get the result
- result = function->invoke(*PHPCPP_G(environment), params);
+ // call the constructor
+ obj->cpp->__construct(*PHPCPP_G(environment), params);
+}
+
+/**
+ * Function that is called by the Zend engine every time the destructor gets called
+ * @param ht
+ * @param return_value
+ * @param return_value_ptr
+ * @param this_ptr
+ * @param return_value_used
+ * @param tsrm_ls
+ */
+static void invoke_destructor(INTERNAL_FUNCTION_PARAMETERS)
+{
+ // get the mixed object
+ MixedObject *obj = (MixedObject *)zend_object_store_get_object(this_ptr TSRMLS_CC);
+
+ // call the destructor
+ obj->cpp->__destruct(*PHPCPP_G(environment));
}
/**
- * Helper struct to create an internal method
+ * Constructor
+ * @param name
*/
+_ClassInfo::_ClassInfo(const char *name) : _name(name), _entry(NULL)
+{
+ // allocate internal functions
+ _constructor = new InternalFunction(invoke_constructor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR);
+ _destructor = new InternalFunction(invoke_destructor, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR);
+}
+/**
+ * Destructor
+ */
+_ClassInfo::~_ClassInfo()
+{
+ // deallocate internal function
+ delete _constructor;
+ delete _destructor;
+}
/**
* Initialize the class
@@ -61,15 +167,16 @@ void _ClassInfo::initialize(TSRMLS_D)
// initialize the class entry
INIT_CLASS_ENTRY_EX(entry, _name.c_str(), _name.size(), NULL);
- // functions we need
- // @todo should not be static
- static InternalFunction constructor(invoke_method, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC);
-
// we need a special constructor
- entry.__call = constructor;
+ entry.create_object = create_object;
+ entry.constructor = _constructor->function();
+ entry.destructor = _destructor->function();
// register the class
_entry = zend_register_internal_class(&entry TSRMLS_CC);
+
+ // store pointer to the class in the unused doc_comment member
+ _entry->info.user.doc_comment = (const char *)this;
}
/**