diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2013-10-15 05:54:52 -0700 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2013-10-15 05:54:52 -0700 |
commit | 61ba30d716dab670a5f2ed0ee2f6650375b2058d (patch) | |
tree | 711db9359015de260071088ef027b020cd95d4b3 | |
parent | b2042dbd58c043ab49e9b0dbb51bf8516fe8cea8 (diff) |
Calling custom member methods is now functional
-rw-r--r-- | include/function.h | 3 | ||||
-rw-r--r-- | include/member.h | 9 | ||||
-rw-r--r-- | include/method.h | 127 | ||||
-rw-r--r-- | include/parameters.h | 23 | ||||
-rw-r--r-- | include/protected.h | 10 | ||||
-rw-r--r-- | include/public.h | 12 | ||||
-rw-r--r-- | phpcpp.h | 1 | ||||
-rw-r--r-- | src/classinfo.cpp | 65 | ||||
-rw-r--r-- | src/function.cpp | 7 | ||||
-rw-r--r-- | src/includes.h | 2 | ||||
-rw-r--r-- | src/member.cpp | 142 | ||||
-rw-r--r-- | src/memberinfo.h | 3 | ||||
-rw-r--r-- | src/members.cpp | 4 | ||||
-rw-r--r-- | src/methodmember.h | 44 | ||||
-rw-r--r-- | src/mixedobject.h | 29 | ||||
-rw-r--r-- | src/parameters.cpp | 18 | ||||
-rw-r--r-- | tests/simple/simple.cpp | 28 | ||||
-rw-r--r-- | tests/simple/simple.php | 19 |
18 files changed, 275 insertions, 271 deletions
diff --git a/include/function.h b/include/function.h index 3cb0e2d..3704ce8 100644 --- a/include/function.h +++ b/include/function.h @@ -140,8 +140,9 @@ protected: * Fill a function entry * @param entry Entry to be filled * @param classname Optional class name + * @param pub Is this a public property? */ - void fill(struct _zend_function_entry *entry, const char *classname=NULL) const; + void fill(struct _zend_function_entry *entry, const char *classname=NULL, bool pub=true) const; /** * Fill function info diff --git a/include/member.h b/include/member.h index 0a7eb29..bc96e52 100644 --- a/include/member.h +++ b/include/member.h @@ -106,14 +106,7 @@ public: * @param pub Is this a public method (otherwise it is protected) * @param method The method to add */ - Member(const char *name, bool pub, method_callback_0 method, const std::initializer_list<Argument> &arguments = {}); - Member(const char *name, bool pub, method_callback_1 method, const std::initializer_list<Argument> &arguments = {}); - Member(const char *name, bool pub, method_callback_2 method, const std::initializer_list<Argument> &arguments = {}); - Member(const char *name, bool pub, method_callback_3 method, const std::initializer_list<Argument> &arguments = {}); - Member(const char *name, bool pub, method_callback_4 method, const std::initializer_list<Argument> &arguments = {}); - Member(const char *name, bool pub, method_callback_5 method, const std::initializer_list<Argument> &arguments = {}); - Member(const char *name, bool pub, method_callback_6 method, const std::initializer_list<Argument> &arguments = {}); - Member(const char *name, bool pub, method_callback_7 method, const std::initializer_list<Argument> &arguments = {}); + Member(const char *name, bool pub, const _Method &method, const std::initializer_list<Argument> &arguments = {}); /** * Copy constructor diff --git a/include/method.h b/include/method.h new file mode 100644 index 0000000..9398fd7 --- /dev/null +++ b/include/method.h @@ -0,0 +1,127 @@ +/** + * Method.h + */ + +/** + * Namespace + */ +namespace Php { + +/** + * A very generic function pointer + */ +typedef void (*function_ptr)(); + +/** + * Base class of the method + */ +class _Method +{ +public: + /** + * Copy constructor + * @param method + */ + _Method(const _Method &method) : _type(method._type), _callback(method._callback) {} + + /** + * Destructor + * @param type + * @param callback + */ + virtual ~_Method() {} + + /** + * Invoke the method + * @param environment + * @param parameters + * @return Value + */ + Value invoke(Environment &environment, Parameters ¶meters) + { + // the object to call a method on + Base *base = parameters.object(); + + // find out which method to call, and call it + switch (_type) { + case 0: (base->*_callback.m0)(); return Value(); + case 1: (base->*_callback.m1)(parameters); return Value(); + case 2: (base->*_callback.m2)(environment); return Value(); + case 3: (base->*_callback.m3)(environment, parameters); return Value(); + case 4: return (base->*_callback.m4)(); + case 5: return (base->*_callback.m5)(parameters); + case 6: return (base->*_callback.m6)(environment); + case 7: return (base->*_callback.m7)(environment, parameters); + default: return Value(); + } + } + +protected: + /** + * Protected constructor to prevent that anyone instantiates this object + */ + _Method(method_callback_0 callback) : _type(0) { _callback.m0 = callback; } + _Method(method_callback_1 callback) : _type(1) { _callback.m1 = callback; } + _Method(method_callback_2 callback) : _type(2) { _callback.m2 = callback; } + _Method(method_callback_3 callback) : _type(3) { _callback.m3 = callback; } + _Method(method_callback_4 callback) : _type(4) { _callback.m4 = callback; } + _Method(method_callback_5 callback) : _type(5) { _callback.m5 = callback; } + _Method(method_callback_6 callback) : _type(6) { _callback.m6 = callback; } + _Method(method_callback_7 callback) : _type(7) { _callback.m7 = callback; } + +private: + /** + * Callback type + * @var int + */ + int _type; + + /** + * The actual callback + * @var void* + */ + union { + method_callback_0 m0; + method_callback_1 m1; + method_callback_2 m2; + method_callback_3 m3; + method_callback_4 m4; + method_callback_5 m5; + method_callback_6 m6; + method_callback_7 m7; + } _callback; +}; + +/** + * Actual template class of the method + */ +template <typename T> +class Method : public _Method +{ +public: + /** + * Constructor + * @param callback + */ + Method(void(T::*callback)()) : _Method(static_cast<method_callback_0>(callback)) {} + Method(void(T::*callback)(Parameters&)) : _Method(static_cast<method_callback_1>(callback)) {} + Method(void(T::*callback)(Environment&)) : _Method(static_cast<method_callback_2>(callback)) {} + Method(void(T::*callback)(Environment&,Parameters&)) : _Method(static_cast<method_callback_3>(callback)) {} + Method(Value(T::*callback)()) : _Method(static_cast<method_callback_4>(callback)) {} + Method(Value(T::*callback)(Parameters&)) : _Method(static_cast<method_callback_5>(callback)) {} + Method(Value(T::*callback)(Environment&)) : _Method(static_cast<method_callback_6>(callback)) {} + Method(Value(T::*callback)(Environment&,Parameters&)) : _Method(static_cast<method_callback_7>(callback)) {} + + /** + * Destructor + */ + virtual ~Method() {} + +}; + +/** + * End of namespace + */ +} + + diff --git a/include/parameters.h b/include/parameters.h index 138d973..b4aca16 100644 --- a/include/parameters.h +++ b/include/parameters.h @@ -13,6 +13,11 @@ namespace Php { /** + * Forward declarations + */ +class Base; + +/** * Class definition */ class Parameters : public std::vector<Value> @@ -20,15 +25,29 @@ class Parameters : public std::vector<Value> public: /** * Constructor - * @param argc Number of arguments + * @param this_ptr Optional this_ptr + * @param argc Number of arguments * @param tsrm_ls */ - Parameters(int argc);// TSRMLS_DC); + Parameters(struct _zval_struct *this_ptr, int argc);// TSRMLS_DC); /** * Destructor */ virtual ~Parameters() {} + + /** + * The the object that is called + * @return Base + */ + Base *object(); + +private: + /** + * The this pointer + * @var zval + */ + struct _zval_struct *_this; }; /** diff --git a/include/protected.h b/include/protected.h index af2c252..f3e668a 100644 --- a/include/protected.h +++ b/include/protected.h @@ -37,15 +37,9 @@ public: * Constructor * @param name Name of the property * @param method Method to add + * @param arguments Optional argument information */ - Protected(const char *name, method_callback_0 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, false, method, arguments) {} - Protected(const char *name, method_callback_1 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, false, method, arguments) {} - Protected(const char *name, method_callback_2 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, false, method, arguments) {} - Protected(const char *name, method_callback_3 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, false, method, arguments) {} - Protected(const char *name, method_callback_4 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, false, method, arguments) {} - Protected(const char *name, method_callback_5 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, false, method, arguments) {} - Protected(const char *name, method_callback_6 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, false, method, arguments) {} - Protected(const char *name, method_callback_7 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, false, method, arguments) {} + Protected(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Member(name, false, method, arguments) {} /** * Destructor diff --git a/include/public.h b/include/public.h index 09625fc..12648a1 100644 --- a/include/public.h +++ b/include/public.h @@ -27,7 +27,7 @@ public: Public(const char *name, std::nullptr_t value) : Member(name, true, value) {} Public(const char *name, int value) : Member(name, true, value) {} Public(const char *name, long value) : Member(name, true, value) {} -// Public(const char *name, bool value) : Member(name, true, value) {} + Public(const char *name, bool value) : Member(name, true, value) {} Public(const char *name, char value) : Member(name, true, value) {} Public(const char *name, const std::string &value) : Member(name, true, value) {} Public(const char *name, const char *value, int size=-1) : Member(name, true, value, size) {} @@ -37,15 +37,9 @@ public: * Constructor * @param name Name of the property * @param method Method to add + * @param arguments Optional argument information */ - Public(const char *name, method_callback_0 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, true, method, arguments) {} - Public(const char *name, method_callback_1 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, true, method, arguments) {} - Public(const char *name, method_callback_2 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, true, method, arguments) {} - Public(const char *name, method_callback_3 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, true, method, arguments) {} - Public(const char *name, method_callback_4 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, true, method, arguments) {} - Public(const char *name, method_callback_5 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, true, method, arguments) {} - Public(const char *name, method_callback_6 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, true, method, arguments) {} - Public(const char *name, method_callback_7 method, const std::initializer_list<Argument> &arguments = {}) : Member(name, true, method, arguments) {} + Public(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Member(name, true, method, arguments) {} /** * Destructor @@ -33,6 +33,7 @@ #include <phpcpp/parameters.h> #include <phpcpp/function.h> #include <phpcpp/base.h> +#include <phpcpp/method.h> #include <phpcpp/member.h> #include <phpcpp/public.h> #include <phpcpp/protected.h> diff --git a/src/classinfo.cpp b/src/classinfo.cpp index a8f7a8d..f1ffb8e 100644 --- a/src/classinfo.cpp +++ b/src/classinfo.cpp @@ -3,7 +3,8 @@ * * Implementation for the class info * - * @documentation private + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV */ #include "includes.h" @@ -13,15 +14,6 @@ namespace Php { /** - * 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 */ @@ -66,8 +58,12 @@ static zend_object_value create_object(zend_class_entry *type TSRMLS_DC) // allocate memory for the object MixedObject *object = (MixedObject *)emalloc(sizeof(MixedObject)); + // find base object + zend_class_entry *base = type; + while (base->parent) base = base->parent; + // retrieve the classinfo object - _ClassInfo *info = (_ClassInfo *)type->info.user.doc_comment; + _ClassInfo *info = (_ClassInfo *)base->info.user.doc_comment; // construct the cpp object object->cpp = info->construct(); @@ -99,53 +95,11 @@ static zend_object_value create_object(zend_class_entry *type TSRMLS_DC) } /** - * 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 - */ -static void invoke_constructor(INTERNAL_FUNCTION_PARAMETERS) -{ - // get the mixed object - MixedObject *obj = (MixedObject *)zend_object_store_get_object(this_ptr TSRMLS_CC); - - // construct parameters - Parameters params(ZEND_NUM_ARGS()); - - // 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)); -} - -/** * 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); } /** @@ -153,9 +107,6 @@ _ClassInfo::_ClassInfo(const char *name) : _name(name), _entry(NULL) */ _ClassInfo::~_ClassInfo() { - // deallocate internal function - delete _constructor; - delete _destructor; } /** @@ -172,8 +123,6 @@ void _ClassInfo::initialize(TSRMLS_DC) // we need a special 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); diff --git a/src/function.cpp b/src/function.cpp index d255518..a4b3fdd 100644 --- a/src/function.cpp +++ b/src/function.cpp @@ -35,7 +35,7 @@ void invoke_function(INTERNAL_FUNCTION_PARAMETERS) Value result(return_value, true); // construct parameters - Parameters params(ZEND_NUM_ARGS()); + Parameters params(this_ptr, ZEND_NUM_ARGS()); // get the result result = function->invoke(*PHPCPP_G(environment), params); @@ -83,8 +83,9 @@ Function::~Function() * * @param entry Entry to be filled * @param classname Optional class name + * @param pub Is this a public property? */ -void Function::fill(zend_function_entry *entry, const char *classname) const +void Function::fill(zend_function_entry *entry, const char *classname, bool pub) const { // fill the members of the entity, and hide a pointer to the current object in the name entry->fname = _ptr; @@ -93,7 +94,7 @@ void Function::fill(zend_function_entry *entry, const char *classname) const entry->num_args = _argc; // there are no flags like deprecated, private or protected - entry->flags = 0; + entry->flags = classname ? (pub ? ZEND_ACC_PUBLIC : ZEND_ACC_PROTECTED) : 0; // we should fill the first argument as well fill((zend_internal_function_info *)entry->arg_info, classname); diff --git a/src/includes.h b/src/includes.h index 2e8271b..0ea9138 100644 --- a/src/includes.h +++ b/src/includes.h @@ -46,6 +46,7 @@ #include "../include/parameters.h" #include "../include/function.h" #include "../include/base.h" +#include "../include/method.h" #include "../include/member.h" #include "../include/public.h" #include "../include/protected.h" @@ -58,6 +59,7 @@ /** * Interface files for internal use only */ +#include "mixedobject.h" #include "nativefunction.h" #include "internalfunction.h" #include "memberinfo.h" diff --git a/src/member.cpp b/src/member.cpp index 5a44a74..d4f5d2d 100644 --- a/src/member.cpp +++ b/src/member.cpp @@ -20,8 +20,6 @@ namespace Php { */ Member::Member(const char *name, bool pub) : _name(name), _public(pub) { - std::cout << "Allocate member " << __LINE__ << std::endl; - // create a null member _info = new NullMember(); } @@ -34,8 +32,6 @@ Member::Member(const char *name, bool pub) : _name(name), _public(pub) */ Member::Member(const char *name, bool pub, std::nullptr_t value) : _name(name), _public(pub) { - std::cout << "Allocate member " << __LINE__ << std::endl; - // create a null member _info = new NullMember(); } @@ -48,8 +44,6 @@ Member::Member(const char *name, bool pub, std::nullptr_t value) : _name(name), */ Member::Member(const char *name, bool pub, int value) : _name(name), _public(pub) { - std::cout << "Allocate member " << __LINE__ << std::endl; - // create a long member _info = new LongMember(value); } @@ -62,8 +56,6 @@ Member::Member(const char *name, bool pub, int value) : _name(name), _public(pub */ Member::Member(const char *name, bool pub, long value) : _name(name), _public(pub) { - std::cout << "Allocate member " << __LINE__ << std::endl; - // create a long member _info = new LongMember(value); } @@ -76,8 +68,6 @@ Member::Member(const char *name, bool pub, long value) : _name(name), _public(pu */ Member::Member(const char *name, bool pub, bool value) : _name(name), _public(pub) { - std::cout << "Allocate member " << __LINE__ << std::endl; - // create a bool member _info = new BoolMember(value); } @@ -90,8 +80,6 @@ Member::Member(const char *name, bool pub, bool value) : _name(name), _public(pu */ Member::Member(const char *name, bool pub, char value) : _name(name), _public(pub) { - std::cout << "Allocate member " << __LINE__ << std::endl; - // create a new string member _info = new StringMember(&value, 1); } @@ -104,8 +92,6 @@ Member::Member(const char *name, bool pub, char value) : _name(name), _public(pu */ Member::Member(const char *name, bool pub, const std::string &value) : _name(name), _public(pub) { - std::cout << "Allocate member " << __LINE__ << std::endl; - // create a new string member _info = new StringMember(value); } @@ -119,8 +105,6 @@ Member::Member(const char *name, bool pub, const std::string &value) : _name(nam */ Member::Member(const char *name, bool pub, const char *value, int size) : _name(name), _public(pub) { - std::cout << "Allocate member " << __LINE__ << std::endl; - // create a new string member if (size < 0) size = strlen(value); _info = new StringMember(value, size); @@ -134,128 +118,18 @@ Member::Member(const char *name, bool pub, const char *value, int size) : _name( */ Member::Member(const char *name, bool pub, double value) : _name(name), _public(pub) { - std::cout << "Allocate member " << __LINE__ << std::endl; - // create a new double member _info = new DoubleMember(value); } /** * Constructor - * @param name Name of the member - * @param pub Is this a public property (otherwise it is protected) - * @param method The method to call - * @param arguments Argument meta data - */ -Member::Member(const char *name, bool pub, method_callback_0 method, const std::initializer_list<Argument> &arguments) : _name(name), _public(pub) -{ - std::cout << "Allocate member " << __LINE__ << std::endl; - - // create method member - _info = new MethodMember(name, method, arguments); -} - -/** - * Constructor - * @param name Name of the member - * @param pub Is this a public property (otherwise it is protected) - * @param method The method to call - * @param arguments Argument meta data - */ -Member::Member(const char *name, bool pub, method_callback_1 method, const std::initializer_list<Argument> &arguments) : _name(name), _public(pub) -{ - std::cout << "Allocate member " << __LINE__ << std::endl; - - // create method member - _info = new MethodMember(name, method, arguments); -} - -/** - * Constructor - * @param name Name of the member - * @param pub Is this a public property (otherwise it is protected) - * @param method The method to call - * @param arguments Argument meta data - */ -Member::Member(const char *name, bool pub, method_callback_2 method, const std::initializer_list<Argument> &arguments) : _name(name), _public(pub) -{ - std::cout << "Allocate member " << __LINE__ << std::endl; - - // create method member - _info = new MethodMember(name, method, arguments); -} - -/** - * Constructor - * @param name Name of the member - * @param pub Is this a public property (otherwise it is protected) - * @param method The method to call - * @param arguments Argument meta data - */ -Member::Member(const char *name, bool pub, method_callback_3 method, const std::initializer_list<Argument> &arguments) : _name(name), _public(pub) -{ - std::cout << "Allocate member " << __LINE__ << std::endl; - - // create method member - _info = new MethodMember(name, method, arguments); -} - -/** - * Constructor - * @param name Name of the member - * @param pub Is this a public property (otherwise it is protected) - * @param method The method to call - * @param arguments Argument meta data - */ -Member::Member(const char *name, bool pub, method_callback_4 method, const std::initializer_list<Argument> &arguments) : _name(name), _public(pub) -{ - std::cout << "Allocate member " << __LINE__ << std::endl; - - // create method member - _info = new MethodMember(name, method, arguments); -} - -/** - * Constructor - * @param name Name of the member - * @param pub Is this a public property (otherwise it is protected) - * @param method The method to call - * @param arguments Argument meta data - */ -Member::Member(const char *name, bool pub, method_callback_5 method, const std::initializer_list<Argument> &arguments) : _name(name), _public(pub) -{ - std::cout << "Allocate member " << __LINE__ << std::endl; - - // create method member - _info = new MethodMember(name, method, arguments); -} - -/** - * Constructor - * @param name Name of the member - * @param pub Is this a public property (otherwise it is protected) - * @param method The method to call - * @param arguments Argument meta data + * @param name Name of the method + * @param pub Is this a public method (otherwise it is protected) + * @param method The method to add */ -Member::Member(const char *name, bool pub, method_callback_6 method, const std::initializer_list<Argument> &arguments) : _name(name), _public(pub) +Member::Member(const char *name, bool pub, const _Method &method, const std::initializer_list<Argument> &arguments) : _name(name), _public(pub) { - std::cout << "Allocate member " << __LINE__ << std::endl; - - // create method member - _info = new MethodMember(name, method, arguments); -} - -/** - * Constructor - * @param name Name of the member - * @param pub Is this a public property (otherwise it is protected) - * @param method The method to call - * @param arguments Argument meta data - */ -Member::Member(const char *name, bool pub, method_callback_7 method, const std::initializer_list<Argument> &arguments) : _name(name), _public(pub) -{ - std::cout << "Allocate member " << __LINE__ << std::endl; - // create method member _info = new MethodMember(name, method, arguments); } @@ -266,8 +140,6 @@ Member::Member(const char *name, bool pub, method_callback_7 method, const std:: */ Member::Member(const Member &member) { - std::cout << "Allocate member " << __LINE__ << std::endl; - // copy info object, and name and public members _info = member._info; _name = member._name; @@ -283,8 +155,6 @@ Member::Member(const Member &member) */ Member::Member(Member &&member) { - std::cout << "Allocate member " << __LINE__ << std::endl; - // move info object, and name and public properties _info = member._info; _name = std::move(member._name); @@ -321,8 +191,6 @@ bool Member::isProperty() */ bool Member::isMethod() { - std::cout << "call isMethod" << std::endl; - return _info && _info->isMethod(); } @@ -345,7 +213,7 @@ void Member::declare(struct _zend_class_entry *entry) void Member::fill(struct _zend_function_entry *entry, const char *classname) { // let the info object do this - _info->fill(entry, classname); + _info->fill(entry, classname, _public); } /** diff --git a/src/memberinfo.h b/src/memberinfo.h index fd9ce3d..040f0de 100644 --- a/src/memberinfo.h +++ b/src/memberinfo.h @@ -73,8 +73,9 @@ public: * Fill a function entry object * @param entry Function entry * @param classname Name of the class + * @param pub Is this a public method? */ - virtual void fill(struct _zend_function_entry *entry, const char *classname) {}; + virtual void fill(struct _zend_function_entry *entry, const char *classname, bool pub) {}; }; diff --git a/src/members.cpp b/src/members.cpp index 5711a4b..4ff1b60 100644 --- a/src/members.cpp +++ b/src/members.cpp @@ -34,8 +34,6 @@ int Members::methods() // loop through the functions for (auto it = begin(); it != end(); it++) { - std::cout << "iter" << std::endl; - // check if this is a method if (it->isMethod()) result++; } @@ -56,8 +54,6 @@ struct _zend_function_entry *Members::methods(const char *classname) // the number of methods int count = methods(); - std::cout << "allocate " << count << " methods" << std::endl; - // allocate memory for the functions _methods = new zend_function_entry[count + 1]; diff --git a/src/methodmember.h b/src/methodmember.h index 16f0dd0..20f2749 100644 --- a/src/methodmember.h +++ b/src/methodmember.h @@ -24,14 +24,7 @@ public: * @param method * @param arguments */ - MethodMember(const char *name, method_callback_0 method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(0) { _method.m0 = method; } - MethodMember(const char *name, method_callback_1 method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(1) { _method.m1 = method; } - MethodMember(const char *name, method_callback_2 method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(2) { _method.m2 = method; } - MethodMember(const char *name, method_callback_3 method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(3) { _method.m3 = method; } - MethodMember(const char *name, method_callback_4 method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(4) { _method.m4 = method; } - MethodMember(const char *name, method_callback_5 method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(5) { _method.m5 = method; } - MethodMember(const char *name, method_callback_6 method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(6) { _method.m6 = method; } - MethodMember(const char *name, method_callback_7 method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(7) { _method.m7 = method; } + MethodMember(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _method(method) {} /** * Destructor @@ -48,34 +41,31 @@ public: * Fill a function entry object * @param entry Function entry * @param classname Name of the class + * @param pub Is this a public entry */ - virtual void fill(struct _zend_function_entry *entry, const char *classname) + virtual void fill(struct _zend_function_entry *entry, const char *classname, bool pub) { // call function object - Function::fill(entry, classname); + Function::fill(entry, classname, pub); } -private: /** - * Union of supported callbacks - * One of the callbacks will be set + * Method that gets called every time the function is executed + * @param environment Environment object + * @param params The parameters that were passed + * @return Variable Return value */ - union { - method_callback_0 m0; - method_callback_1 m1; - method_callback_2 m2; - method_callback_3 m3; - method_callback_4 m4; - method_callback_5 m5; - method_callback_6 m6; - method_callback_7 m7; - } _method; - + virtual Value invoke(Environment &environment, Parameters ¶ms) + { + return _method.invoke(environment, params); + } + +private: /** - * The method type that is set - * @var integer + * The method pointer + * @var _Method */ - int _type; + _Method _method; }; /** diff --git a/src/mixedobject.h b/src/mixedobject.h new file mode 100644 index 0000000..55a27ec --- /dev/null +++ b/src/mixedobject.h @@ -0,0 +1,29 @@ +/** + * MixedObject.h + * + * Structure that combines a Zend object with an object in C++ + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Structure that combines a C++ object with a zend object + */ +struct MixedObject +{ + zend_object php; + Base *cpp; +}; + +/** + * End of namespace + */ +} + + diff --git a/src/parameters.cpp b/src/parameters.cpp index d31f49c..2fb2eef 100644 --- a/src/parameters.cpp +++ b/src/parameters.cpp @@ -13,10 +13,11 @@ namespace Php { /** * Parameters - * @param argc Number of arguments + * @param this_ptr Pointer to the object + * @param argc Number of arguments * @param tsrm_ls */ -Parameters::Parameters(int argc TSRMLS_DC) +Parameters::Parameters(zval *this_ptr, int argc TSRMLS_DC) : _this(this_ptr) { // reserve plenty of space reserve(argc); @@ -33,6 +34,19 @@ Parameters::Parameters(int argc TSRMLS_DC) } /** + * The the object that is called + * @return Base + */ +Base *Parameters::object() +{ + // get the mixed object + MixedObject *obj = (MixedObject *)zend_object_store_get_object(_this TSRMLS_CC); + + // return the CPP object + return obj->cpp; +} + +/** * End of namespace */ } diff --git a/tests/simple/simple.cpp b/tests/simple/simple.cpp index b3f30bc..e90fe55 100644 --- a/tests/simple/simple.cpp +++ b/tests/simple/simple.cpp @@ -23,8 +23,9 @@ using namespace std; */ static Php::Value my_plus(Php::Environment &env, Php::Parameters ¶ms) { - string p1 = params[0]; - string p2 = params[1]; + int p1 = params[0]; + int p2 = params[1]; + return p1 + p2; cout << "global g1: " << env["g1"].stringValue() << endl; cout << "global g2: " << env["g2"].stringValue() << endl; @@ -53,6 +54,8 @@ public: { _x = 3; cout << "MyCustomClass::MyCustomClass" << endl; + cout << this << endl; + cout << _x << endl; } virtual ~MyCustomClass() @@ -72,6 +75,10 @@ public: void myMethod(Php::Parameters ¶ms) { + cout << "myMethod GETS CALLED!!!!" << endl; + cout << this << endl; + cout << _x << endl; + } }; @@ -86,17 +93,20 @@ extern "C" // define the functions extension.add("my_plus", my_plus, { - Php::ByVal("a", Php::stringType), - Php::ByVal("b", Php::arrayType), - Php::ByVal("c", "MyClass"), - Php::ByRef("d", Php::stringType) + Php::ByVal("a", Php::longType), + Php::ByVal("b", Php::longType) +// Php::ByVal("c", "MyClass"), +// Php::ByRef("d", Php::stringType) }); + Php::Method<MyCustomClass> x(&MyCustomClass::myMethod); + // define classes extension.add("my_class", Php::Class<MyCustomClass>({ -// Php::Public("a", 123), -// Php::Protected("b", "abc"), - Php::Public("myMethod", static_cast<Php::method_callback_1>(&MyCustomClass::myMethod)) + Php::Public("a", 123), + Php::Protected("b", "abc"), + Php::Protected("myMethod", Php::Method<MyCustomClass>(&MyCustomClass::myMethod)), + Php::Public("__construct", Php::Method<MyCustomClass>(&MyCustomClass::__construct)) })); // return the module entry diff --git a/tests/simple/simple.php b/tests/simple/simple.php index 379f285..345c139 100644 --- a/tests/simple/simple.php +++ b/tests/simple/simple.php @@ -34,8 +34,23 @@ if (class_exists("my_class")) echo("Warempel, de class bestaat\n"); -$x = new my_class(); -$x->myMethod(); +class my_extended_class extends my_class +{ + public function myMethod($val) + { + echo($this->a."\n"); + echo($this->b."\n"); + echo("hoi\n"); + + parent::myMethod($val); + } + +} + +$x = new my_extended_class(); +$x->myMethod(123); + +my_plus(1,2,3,4); //echo("my_class::a = ".$x->a."\n"); //echo("my_class::b = ".$x->b."\n"); |