]> granicus.if.org Git - php/commitdiff
blah
authorHarald Radi <phanto@php.net>
Sat, 16 Mar 2002 16:15:34 +0000 (16:15 +0000)
committerHarald Radi <phanto@php.net>
Sat, 16 Mar 2002 16:15:34 +0000 (16:15 +0000)
ext/rpc/RPC_HOWTO [new file with mode: 0644]
ext/rpc/com/com.c
ext/rpc/handler.h
ext/rpc/php_rpc.h
ext/rpc/rpc.c
ext/rpc/rpc.h
ext/rpc/tests/test1.php

diff --git a/ext/rpc/RPC_HOWTO b/ext/rpc/RPC_HOWTO
new file mode 100644 (file)
index 0000000..9b6e92b
--- /dev/null
@@ -0,0 +1,97 @@
+what's this ?
+=============
+
+This is an abstraction layer that eases the task of writing rpc
+extensions (e.g. java, com, corba, soap, srm, .net, xml-rpc, ..).
+it maps the quite complex ZendEngine2 oo api to a few simpler to
+handle callback functions declared in the 'rpc_object_handlers'
+struct.
+
+so what happens behind my back ?
+================================
+
+- the abstraction layer takes care of your underlaying data structure
+and passes it to you each time you have to handle an operation.
+- it does reference counting and tells you when you have to destruct
+your underlaying data structure.
+- it registers a class and four functions (xxx_load, xxx_call, xxx_get,
+xxx_set) for your rpc layer and checks if the parameters are valid (beside
+the ones that are optional for your rpc layer).
+- it silently creates proxies for references to members of your rpc
+objects.
+- it optionally does object pooling for objects that support it (has to
+be defined in the constructor)
+- it optionally requests hash values for method and property names and
+caches them. call / get and set requests will then receive the hash value
+instead of the original function- / propertyname.
+
+how can i make use of it ?
+==========================
+
+take ext/rpc/com/com.c as a starting point. you'll have to set up the following struct:
+
+typedef struct _rpc_object_handlers {
+       int (*rpc_hash)(char *name, zend_uint name_len, char **hash, zend_uint *hash_len, int type);
+       int hash_type;
+       int (*rpc_ctor)(char *class_name, zend_uint class_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS);
+       int (*rpc_dtor)(void **data);
+       int (*rpc_call)(char *method_name, zend_uint method_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS);
+       int (*rpc_get)(char *property_name, zend_uint property_name_len, zval *return_value, void **data);
+       int (*rpc_set)(char *property_name, zend_uint property_name_len, zval *value, zval *return_value, void **data);
+       int (*rpc_compare)(void **data1, void **data2);
+       int (*rpc_get_classname)(char **class_name, zend_uint *class_name_length, void **data);
+       int (*rpc_has_property)(char *property_name, zend_uint property_name_length, void **data);
+       int (*rpc_unset_property)(char *property_name, zend_uint property_name_length, void **data);
+       int (*rpc_get_properties)(HashTable **properties, void **data);
+} rpc_object_handlers;
+
+
+rpc_hash:
+the hashing function for method and property names. returns a hash value
+for the string passed in 'name'. 'type' is either METHOD or PROPERTY.
+if you set 'hash_type' to HASH_AS_INT you can set '*hash' to NULL and pass
+the hash value as 'hash_len'.
+rpc_hash can be set to NULL if hashing of method and property names is not
+appreciated.
+
+hash_type:
+either HASH_AS_INT, HASH_AS_STRING or DONT_HASH
+
+rpc_ctor:
+the constructor
+
+rpc_dtor:
+the destructor
+
+rpc_call:
+the call handler
+
+rpc_get:
+the get handler
+
+rpc_set:
+the set handler
+
+rpc_compare:
+the compare handler.
+rpc_compare can be set to NULL then objects will be treated the same if they
+belong to the same rpc layer.
+
+rpc_get_classname:
+returns the classname.
+rpc_get_classname can be set to NULL then the name of the rpc layer will be
+used as classname.
+
+rpc_has_property:
+check if a property exists.
+rpc_has_property can be set to NULL then true will be returned for every request.
+
+rpc_unset_property:
+unset a property.
+rpc_unset_property can be set to NULL, a 'not supported' warning will then be
+issued.
+
+rpc_get_properties:
+returns a HashTable with all the properties.
+rpc_get_properties can be set to NULL, then a list of the explicit declared
+properties will be returned.
index c481e653ec671dea7b5cd1633885abfe03d2df7d..d43abb8f060bf1aff1c5054a981246e38e407d16 100644 (file)
-#include <stdio.h>
-#include "../handler.h"
-#include "../php_rpc.h"
+#include "com.h"
 
-RPC_REGISTER_HANDLERS(com)
+/* protos */
+static int com_hash(char *name, zend_uint name_len, char **hash, zend_uint *hash_len, int type);
+static int com_ctor(char *class_name, zend_uint class_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS);
+static int com_dtor(void **data);
+static int com_call(char *method_name, zend_uint method_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS);
+static int com_get(char *property_name, zend_uint property_name_len, zval *return_value, void **data);
+static int com_set(char *property_name, zend_uint property_name_len, zval *value, zval *return_value, void **data);
+static int com_compare(void **data1, void **data2);
+static int com_get_classname(char **class_name, zend_uint *class_name_length, void **data);
+static int com_has_property(char *property_name, zend_uint property_name_length, void **data);
+static int com_unset_property(char *property_name, zend_uint property_name_length, void **data);
+static int com_get_properties(HashTable **properties, void **data);
 
+
+/* register rpc callback function */
+RPC_REGISTER_HANDLERS_START(com, DONT_POOL)
+com_hash,
+HASH_AS_STRING,
+com_ctor,
+com_dtor,
+com_call,
+com_get,
+com_set,
+com_compare,
+com_get_classname,
+com_has_property,
+com_unset_property,
+com_get_properties
+RPC_REGISTER_HANDLERS_END()
+
+/* register userspace functions */
 RPC_FUNCTION_ENTRY_START(com)
+       ZEND_FALIAS(com_invoke, rpc_call, NULL)
+       ZEND_FE(com_addref, NULL)
 RPC_FUNCTION_ENTRY_END()
 
-RPC_INIT_FUNCTION(com) {
+/* register class methods */
+RPC_METHOD_ENTRY_START(com)
+       ZEND_FALIAS(addref, com_addref, NULL)
+RPC_METHOD_ENTRY_END()
+
+/* init function that is called before the class is registered
+ * so you can do any tricky stuff in here
+ */
+RPC_INIT_FUNCTION(com)
+{
+}
+
+/* rpc handler functions */
+
+static int com_hash(char *name, zend_uint name_len, char **hash, zend_uint *hash_len, int type)
+{
+       return SUCCESS;
+}
+
+static int com_ctor(char *class_name, zend_uint class_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS)
+{
+       return SUCCESS;
+}
+
+static int com_dtor(void **data)
+{
+       return SUCCESS;
+}
+
+static int com_call(char *method_name, zend_uint method_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS)
+{
+       return SUCCESS;
+}
+
+static int com_get(char *property_name, zend_uint property_name_len, zval *return_value, void **data)
+{
+       return SUCCESS;
 }
+
+static int com_set(char *property_name, zend_uint property_name_len, zval *value, zval *return_value, void **data)
+{
+       return SUCCESS;
+}
+
+static int com_compare(void **data1, void **data2)
+{
+       return SUCCESS;
+}
+
+static int com_get_classname(char **class_name, zend_uint *class_name_length, void **data)
+{
+       return SUCCESS;
+}
+
+static int com_has_property(char *property_name, zend_uint property_name_length, void **data)
+{
+       return SUCCESS;
+}
+
+static int com_unset_property(char *property_name, zend_uint property_name_length, void **data)
+{
+       return SUCCESS;
+}
+
+static int com_get_properties(HashTable **properties, void **data)
+{
+       return SUCCESS;
+}
+
+/* custom functions */
+ZEND_FUNCTION(com_addref)
+{
+}
\ No newline at end of file
index 3e60ba77f45800bf0eddaa3e95fdc758b664717a..51a25c86a4981123849344f228c62f7c0cf62506 100644 (file)
@@ -3,46 +3,87 @@
 
 #include "php.h"
 
-#define RPC_HANDLER(layer)                             {#layer, layer##_handler_init, &layer##_object_handlers, &layer##_class_entry, layer##_function_entry}
+#define RPC_HANDLER(layer)                             {#layer, layer##_handler_init, &layer##_object_handlers,        \
+                                                                               &layer##_class_entry, layer##_function_entry,                           \
+                                                                               layer##_method_entry, &layer##_pool}
 
 #define RPC_DECLARE_HANDLER(layer)             void layer##_handler_init();                                    \
+                                                                               const int layer##_pool;                                                         \
                                                                                rpc_object_handlers layer##_object_handlers;    \
                                                                                zend_class_entry layer##_class_entry;                   \
-                                                                               function_entry layer##_function_entry[];
+                                                                               function_entry layer##_function_entry[];                \
+                                                                               function_entry layer##_method_entry[];
 
 #define RPC_INIT_FUNCTION(layer)               void layer##_handler_init()
 
-#define RPC_REGISTER_HANDLERS(layer)   zend_class_entry layer##_class_entry;                   \
-                                                                               rpc_object_handlers layer##_object_handlers;    \
+#define RPC_REGISTER_HANDLERS_START(layer, p)  zend_class_entry layer##_class_entry;                           \
+                                                                                               const int layer##_pool = p;                                                     \
+                                                                                               rpc_object_handlers layer##_object_handlers = {
+
+#define RPC_REGISTER_HANDLERS_END()                            };
 
   
 #define RPC_FUNCTION_ENTRY_START(layer)        function_entry layer##_function_entry[] = {             \
-                                                                                       PHP_FALIAS(layer##_load, rpc_load, NULL)        \
-                                                                                       PHP_FALIAS(layer##_call, rpc_call, NULL)        \
-                                                                                       PHP_FALIAS(layer##_get, rpc_get, NULL)          \
-                                                                                       PHP_FALIAS(layer##_set, rpc_set, NULL)
+                                                                                       ZEND_FALIAS(layer##_load, rpc_load, NULL)       \
+                                                                                       ZEND_FALIAS(layer##_call, rpc_call, NULL)       \
+                                                                                       ZEND_FALIAS(layer##_get, rpc_get, NULL)         \
+                                                                                       ZEND_FALIAS(layer##_set, rpc_set, NULL)
 
 #define RPC_FUNCTION_ENTRY_END()                       {NULL, NULL, NULL}                                                      \
                                                                                };
 
+#define RPC_METHOD_ENTRY_START(layer)  function_entry layer##_method_entry[] = {
+
+#define RPC_METHOD_ENTRY_END()                         {NULL, NULL, NULL}                                                      \
+                                                                               };
+
+#define POOL           TRUE
+#define DONT_POOL      FALSE
+#define HASH_AS_INT    TRUE
+#define HASH_AS_STRING FALSE
+#define DONT_HASH      FALSE
+
+#define METHOD 0
+#define PROPERTY 1
+
 
+/* rpc handler that have to be implemented by a 
+ * specific rpc layer
+ */
 typedef struct _rpc_object_handlers {
-       int i;
+       int (*rpc_hash)(char *name, zend_uint name_len, char **hash, zend_uint *hash_len, int type);
+       int hash_type;
+       int (*rpc_ctor)(char *class_name, zend_uint class_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS);
+       int (*rpc_dtor)(void **data);
+       int (*rpc_call)(char *method_name, zend_uint method_name_len, void **data, INTERNAL_FUNCTION_PARAMETERS);
+       int (*rpc_get)(char *property_name, zend_uint property_name_len, zval *return_value, void **data);
+       int (*rpc_set)(char *property_name, zend_uint property_name_len, zval *value, zval *return_value, void **data);
+       int (*rpc_compare)(void **data1, void **data2);
+       int (*rpc_get_classname)(char **class_name, zend_uint *class_name_length, void **data);
+       int (*rpc_has_property)(char *property_name, zend_uint property_name_length, void **data);
+       int (*rpc_unset_property)(char *property_name, zend_uint property_name_length, void **data);
+       int (*rpc_get_properties)(HashTable **properties, void **data);
 } rpc_object_handlers;
 
+/* handler entry */
 typedef struct _rpc_handler_entry {
        char                            *name;
        void (*rpc_handler_init)();
        rpc_object_handlers     *handlers;
        zend_class_entry        *ce;
        function_entry          *functions;
+       function_entry          *methods;
+       const int                       *pool_instances;
 } rpc_handler_entry;
 
+/* internal data */
 typedef struct _rpc_internal {
        zend_class_entry        *ce;
        rpc_object_handlers     **handlers;
-       void                            *data;
-       int                                     refcount;
+       void                            **data;
+       unsigned                        refcount;
+       unsigned                        clonecount;
+       int                                     pool_instances;
 } rpc_internal;
 
 #endif /* HANDLER_H */
\ No newline at end of file
index 96e4e219428d821785e359af9af21830c5ab402b..be95b209409efe3fdbe347a17194a0b9de9ce0b5 100644 (file)
@@ -16,9 +16,9 @@ extern zend_module_entry rpc_module_entry;
 #include "TSRM.h"
 #endif
 
-PHP_MINIT_FUNCTION(rpc);
-PHP_MSHUTDOWN_FUNCTION(rpc);
-PHP_MINFO_FUNCTION(rpc);
+ZEND_MINIT_FUNCTION(rpc);
+ZEND_MSHUTDOWN_FUNCTION(rpc);
+ZEND_MINFO_FUNCTION(rpc);
 
 ZEND_FUNCTION(rpc_load);
 ZEND_FUNCTION(rpc_call);
index b0d5af2375851faae664b0645a08fcd6301cedc3..ade9afc42095fe4dbb9980e87413037d2fdd93f2 100644 (file)
@@ -27,7 +27,6 @@ static zend_object_value rpc_clone(zval *object TSRMLS_DC);
 static zval* rpc_read(zval *object, zval *member, int type TSRMLS_DC);
 static void rpc_write(zval *object, zval *member, zval *value TSRMLS_DC);
 static zval** rpc_get_property(zval *object, zval *member TSRMLS_DC);
-static zval** rpc_get_property_zval(zval *object, zval *member TSRMLS_DC);
 static zval* rpc_get(zval *property TSRMLS_DC);
 static void rpc_set(zval **property, zval *value TSRMLS_DC);
 static int rpc_has_property(zval *object, zval *member, int check_empty TSRMLS_DC);
@@ -48,7 +47,7 @@ static zend_object_handlers rpc_handlers = {
        rpc_read,
        rpc_write,
        rpc_get_property,
-       rpc_get_property_zval,
+       NULL,
        rpc_get,
        rpc_set,
        rpc_has_property,
@@ -74,11 +73,11 @@ zend_module_entry rpc_module_entry = {
        STANDARD_MODULE_HEADER,
        "rpc",
        rpc_functions,
-       PHP_MINIT(rpc),
-       PHP_MSHUTDOWN(rpc),
+       ZEND_MINIT(rpc),
+       ZEND_MSHUTDOWN(rpc),
        NULL,
        NULL,
-       PHP_MINFO(rpc),
+       ZEND_MINFO(rpc),
        "0.1a",
        STANDARD_MODULE_PROPERTIES
 };
@@ -120,7 +119,7 @@ static int rpc_global_startup(void)
                /* create a class entry for every rpc handler */
                INIT_OVERLOADED_CLASS_ENTRY((*(HANDLER.ce)),
                                                                        HANDLER.name,
-                                                                       NULL,
+                                                                       HANDLER.methods,
                                                                        NULL,
                                                                        NULL,
                                                                        NULL);
@@ -149,9 +148,9 @@ static void rpc_globals_ctor(zend_rpc_globals *rpc_globals TSRMLS_DC)
 {
 }
 
-/* {{{ PHP_MINIT_FUNCTION
+/* {{{ ZEND_MINIT_FUNCTION
  */
-PHP_MINIT_FUNCTION(rpc)
+ZEND_MINIT_FUNCTION(rpc)
 {
        /* GINIT */
        if (thread_count++ == 0) {
@@ -171,9 +170,9 @@ PHP_MINIT_FUNCTION(rpc)
 }
 /* }}} */
 
-/* {{{ PHP_MSHUTDOWN_FUNCTION
+/* {{{ ZEND_MSHUTDOWN_FUNCTION
  */
-PHP_MSHUTDOWN_FUNCTION(rpc)
+ZEND_MSHUTDOWN_FUNCTION(rpc)
 {
        /* GSHUTDOWN */
        if (--thread_count == 0) {
@@ -185,9 +184,9 @@ PHP_MSHUTDOWN_FUNCTION(rpc)
 }
 /* }}} */
 
-/* {{{ PHP_MINFO_FUNCTION
+/* {{{ ZEND_MINFO_FUNCTION
  */
-PHP_MINFO_FUNCTION(rpc)
+ZEND_MINFO_FUNCTION(rpc)
 {
        php_info_print_table_start();
        php_info_print_table_header(2, "rpc support", "enabled");
@@ -203,7 +202,9 @@ static void rpc_instance_dtor(void *pDest)
        
        intern = (rpc_internal **) pDest;
 
-       /* TODO: destruct intern */
+       /* TODO: destruct custom data */
+
+       pefree(*intern, TRUE);
 }
 
 static zend_object_value rpc_create_object(zend_class_entry *class_type TSRMLS_DC)
@@ -218,7 +219,8 @@ static zend_object_value rpc_create_object(zend_class_entry *class_type TSRMLS_D
        /* set up the internal representation of our rpc instance */
        intern = (rpc_internal *) pemalloc(sizeof(rpc_internal), TRUE);
        intern->ce = class_type;
-       intern->refcount = 0;
+       intern->refcount = 1;
+       intern->clonecount = 1;
        intern->data = NULL;
        if (zend_hash_find(handlers, class_type->name, class_type->name_length + 1, (void **) &(intern->handlers)) == FAILURE) {
                /* TODO: exception */
@@ -247,29 +249,48 @@ static void rpc_add_ref(zval *object TSRMLS_DC)
 
 static void rpc_del_ref(zval *object TSRMLS_DC)
 {
-       GET_INTERNAL(intern);
+       rpc_internal **intern;
 
-       if (RPC_REFCOUNT(intern) > 0) {
-               RPC_DELREF(intern);
-       }
+       if (GET_INTERNAL_EX(intern, object) == SUCCESS) {
+               if (RPC_REFCOUNT(intern) > 0) {
+                       RPC_DELREF(intern);
+               }
 
-       if (RPC_REFCOUNT(intern) == 0) {
-               rpc_instance_dtor(intern);
+               if (RPC_REFCOUNT(intern) == 0) {
+                       zend_hash_index_del(instance, Z_OBJ_HANDLE(*object));
+               }
        }
 }
 
 static void rpc_delete(zval *object TSRMLS_DC)
 {
-       GET_INTERNAL(intern);
-       rpc_instance_dtor(intern);
+       rpc_internal **intern;
+       
+       if (GET_INTERNAL_EX(intern, object) == SUCCESS) {
+               if (RPC_CLONECOUNT(intern) > 0) {
+                       RPC_DELCLONE(intern);
+               }
+
+               if (RPC_CLONECOUNT(intern) == 0) {
+                       zend_hash_index_del(instance, Z_OBJ_HANDLE_P(object));
+               }
+       }
 }
 
 static zend_object_value rpc_clone(zval *object TSRMLS_DC)
 {
-//     TSRMLS_FETCH();
-//     GET_INTERNAL(intern);
+       GET_INTERNAL(intern);
+
+       /* cloning the underlaying resource is neither possible nor would it
+        * make sense, therfore we return the old zend_object_value and increase
+        * the clone count to not loose the clone when the original object gets
+        * deleted.
+        */
+       RPC_ADDCLONE(intern);
+       
+       /* also increase the refcounter as a clone is just another reference */
+       RPC_ADDREF(intern);
 
-       /* FIXME */
        return object->value.obj;
 }
 
@@ -289,14 +310,8 @@ static void rpc_write(zval *object, zval *member, zval *value TSRMLS_DC)
 
 static zval** rpc_get_property(zval *object, zval *member TSRMLS_DC)
 {
-//     GET_INTERNAL(intern);
-
-       /* FIXME */
-       return NULL;
-}
+/* no idea how to return an object - wait for andi */
 
-static zval** rpc_get_property_zval(zval *object, zval *member TSRMLS_DC)
-{
 //     GET_INTERNAL(intern);
 
        /* FIXME */
@@ -342,16 +357,16 @@ static HashTable* rpc_get_properties(zval *object TSRMLS_DC)
 static union _zend_function* rpc_get_method(zval *object, char *method, int method_len TSRMLS_DC)
 {
        zend_function *function;
+       GET_INTERNAL(intern);
 
-       function = (zend_function *) emalloc(sizeof(zend_function));
-       function->type = ZEND_OVERLOADED_FUNCTION;
-       function->common.arg_types = NULL;
-       function->common.function_name = method;
-       function->common.scope = NULL;
-
-       //      GET_INTERNAL(intern);
+       if (zend_hash_find(&((*intern)->ce->function_table), method, method_len + 1, &function) == FAILURE) {
+               function = (zend_function *) emalloc(sizeof(zend_function));
+               function->type = ZEND_OVERLOADED_FUNCTION;
+               function->common.arg_types = NULL;
+               function->common.function_name = method;
+               function->common.scope = NULL;
+       }
 
-       /* FIXME */
        return function;
 }
 
@@ -412,7 +427,7 @@ ZEND_FUNCTION(rpc_load)
                /* the name of the rpc layer is prepended to '_load' so lets strip everything after
                 * the first '_' away from the function name
                 */
-               zend_class_entry *ce;
+               zend_class_entry **ce;
                key = estrdup(get_active_function_name(TSRMLS_C));
                key_len = strchr(key, '_') - key;
                key[key_len] = '\0';
@@ -420,7 +435,6 @@ ZEND_FUNCTION(rpc_load)
                /* get the class entry for the requested rpc layer */
                if (zend_hash_find(CG(class_table), key, key_len + 1, (void **) &ce) == FAILURE) {
                        /* TODO: exception here */
-                       RETURN_FALSE;
                }
 
                /* set up a new zval container */
@@ -428,18 +442,21 @@ ZEND_FUNCTION(rpc_load)
                INIT_PZVAL(object);
 
                Z_TYPE_P(object) = IS_OBJECT;
-               ZVAL_REFCOUNT(object) = 1;
-               PZVAL_IS_REF(object) = 1;
 
                /* create a new object */
-               object->value.obj = rpc_create_object(ce TSRMLS_CC);
+               object->value.obj = rpc_create_object(*ce TSRMLS_CC);
 
+               /* return the newly created object */
                return_value = object;
 
                /* now everything is set up the same way as if we were called as a constructor */
        }
 
-       GET_INTERNAL_EX(intern, object);
+       if (GET_INTERNAL_EX(intern, object) == FAILURE) {
+               /* TODO: exception */
+       }
+
+//     (*intern)->handlers.rpc_ctor(
 
        /* FIXME */
 }
index bdffa8665cb43a2d7f75e6c4eda5ca0b3a513659..5219583ead46e17a6c72a58af9528b40a019d544 100644 (file)
@@ -5,16 +5,21 @@
 #define HANDLER handler_entries[__handler_counter]
 #define HANDLER_COUNT (sizeof(handler_entries) / sizeof(rpc_handler_entry))
 
-#define GET_INTERNAL(intern)   rpc_internal **intern;                  \
-                                                               GET_INTERNAL_EX(intern, object)
-#define GET_INTERNAL_EX(intern, object)        if (zend_hash_index_find(instance, object->value.obj.handle, (void **) &intern) == FAILURE) {   \
-                                                                                       /* TODO: exception */                                                                                                                                           \
-                                                                               }
+#define GET_INTERNAL(intern)   rpc_internal **intern;                                                          \
+                                                               if (GET_INTERNAL_EX(intern, object) == FAILURE) {       \
+                                                                       /* TODO: exception */                                                   \
+                                                               }
+
+#define GET_INTERNAL_EX(intern, object)        zend_hash_index_find(instance, object->value.obj.handle, (void **) &intern)
 
 #define RPC_REFCOUNT(intern) ((*intern)->refcount)
 #define RPC_ADDREF(intern) (++RPC_REFCOUNT(intern))
 #define RPC_DELREF(intern) (--RPC_REFCOUNT(intern))
 
+#define RPC_CLONECOUNT(intern) ((*intern)->clonecount)
+#define RPC_ADDCLONE(intern) (++RPC_CLONECOUNT(intern))
+#define RPC_DELCLONE(intern) (--RPC_CLONECOUNT(intern))
+
 static int __handler_counter;
 
 #endif
\ No newline at end of file
index 97e884bf744ef388dbdc7a590b614f55fc240fa5..e8bf24ef67a6bc7835ca03b57e68d60cddb06277 100644 (file)
@@ -3,9 +3,19 @@ print "huhuhdsa";
 
 $rpc = new com();
 $rpc->call();
+$rpc->addref();
+
+$clone = $rpc->__clone();
+
+//$rpc->prop = 1;
+//$a = $rpc->prop;
+
+$a = &$rpc->prop;
+
 delete $rpc;
+delete $clone;
 
 $heh = com_load();
-$heh->call;
-delete $heh;
+/*$heh->call;
+delete $heh;*/
 ?>
\ No newline at end of file