*/
function_entry spl_functions[] = {
PHP_FE(spl_classes, NULL)
- PHP_FE(class_name, NULL)
PHP_FE(class_parents, NULL)
PHP_FE(class_implements, NULL)
{NULL, NULL, NULL}
{
ZEND_INIT_MODULE_GLOBALS(spl, spl_init_globals, NULL);
- REGISTER_SPL_INTERFACE(spl, iterator);
- REGISTER_SPL_INTF_FUNC(spl, iterator, new_iterator);
+ REGISTER_SPL_INTERFACE(iterator);
+ REGISTER_SPL_INTF_FUNC(iterator, new_iterator);
- REGISTER_SPL_INTERFACE(spl, forward);
- REGISTER_SPL_INTF_FUNC(spl, forward, current);
- REGISTER_SPL_INTF_FUNC(spl, forward, next);
- REGISTER_SPL_INTF_FUNC(spl, forward, has_more);
+ REGISTER_SPL_INTERFACE(forward);
+ REGISTER_SPL_INTF_FUNC(forward, current);
+ REGISTER_SPL_INTF_FUNC(forward, next);
+ REGISTER_SPL_INTF_FUNC(forward, has_more);
- REGISTER_SPL_INTERFACE(spl, sequence);
- REGISTER_SPL_INTF_FUNC(spl, sequence, rewind);
- REGISTER_SPL_IMPLEMENT(spl, sequence, forward);
+ REGISTER_SPL_INTERFACE(sequence);
+ REGISTER_SPL_INTF_FUNC(sequence, rewind);
+ REGISTER_SPL_IMPLEMENT(sequence, forward);
- REGISTER_SPL_INTERFACE(spl, assoc);
- REGISTER_SPL_INTF_FUNC(spl, assoc, key);
+ REGISTER_SPL_INTERFACE(assoc);
+ REGISTER_SPL_INTF_FUNC(assoc, key);
- REGISTER_SPL_INTERFACE(spl, forward_assoc);
- REGISTER_SPL_IMPLEMENT(spl, forward_assoc, assoc);
- REGISTER_SPL_IMPLEMENT(spl, forward_assoc, forward);
+ REGISTER_SPL_INTERFACE(forward_assoc);
+ REGISTER_SPL_IMPLEMENT(forward_assoc, assoc);
+ REGISTER_SPL_IMPLEMENT(forward_assoc, forward);
- REGISTER_SPL_INTERFACE(spl, sequence_assoc);
- REGISTER_SPL_IMPLEMENT(spl, sequence_assoc, forward_assoc);
- REGISTER_SPL_IMPLEMENT(spl, sequence_assoc, sequence);
+ REGISTER_SPL_INTERFACE(sequence_assoc);
+ REGISTER_SPL_IMPLEMENT(sequence_assoc, forward_assoc);
+ REGISTER_SPL_IMPLEMENT(sequence_assoc, sequence);
- REGISTER_SPL_INTERFACE(spl, array_read);
- REGISTER_SPL_INTF_FUNC(spl, array_read, get);
- REGISTER_SPL_INTF_FUNC(spl, array_read, exists);
+ REGISTER_SPL_INTERFACE(array_read);
+ REGISTER_SPL_INTF_FUNC(array_read, get);
+ REGISTER_SPL_INTF_FUNC(array_read, exists);
- REGISTER_SPL_INTERFACE(spl, array_access);
- REGISTER_SPL_IMPLEMENT(spl, array_access, array_read);
- REGISTER_SPL_INTF_FUNC(spl, array_access, set);
+ REGISTER_SPL_INTERFACE(array_access);
+ REGISTER_SPL_IMPLEMENT(array_access, array_read);
+ REGISTER_SPL_INTF_FUNC(array_access, set);
- REGISTER_SPL_INTERFACE(spl, array_access_ex);
- REGISTER_SPL_IMPLEMENT(spl, array_access_ex, array_access);
- REGISTER_SPL_INTF_FUNC(spl, array_access_ex, new_writer);
+ REGISTER_SPL_INTERFACE(array_access_ex);
+ REGISTER_SPL_IMPLEMENT(array_access_ex, array_access);
+ REGISTER_SPL_INTF_FUNC(array_access_ex, new_writer);
- REGISTER_SPL_INTERFACE(spl, array_writer);
- REGISTER_SPL_INTF_FUNC(spl, array_writer, set);
+ REGISTER_SPL_INTERFACE(array_writer);
+ REGISTER_SPL_INTF_FUNC(array_writer, set);
#ifdef SPL_ARRAY_WRITE
- REGISTER_SPL_STD_CLASS(spl, array_writer_default, spl_array_writer_default_create);
- REGISTER_SPL_FUNCTIONS(spl, array_writer_default, spl_array_writer_funcs);
+ REGISTER_SPL_STD_CLASS(array_writer_default, spl_array_writer_default_create);
+ REGISTER_SPL_FUNCTIONS(array_writer_default, spl_array_writer_funcs);
#endif
return SUCCESS;
}
/* }}} */
-/* {{{ proto string class_name(object)
- Retrieve */
-PHP_FUNCTION(class_name)
-{
- zval *obj;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
- RETURN_FALSE;
- }
- RETURN_STRING(spl_make_fully_qualyfied_name(Z_OBJCE_P(obj) TSRMLS_CC), 0);
-}
-/* }}} */
-
/* {{{ class_parents
*/
PHP_FUNCTION(class_parents)
#endif /* SPL_ARRAY_WRITE */
PHP_FUNCTION(spl_classes);
-PHP_FUNCTION(class_name);
PHP_FUNCTION(class_parents);
PHP_FUNCTION(class_implements);
/* {{{ spl_call_method */
int spl_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len, zval **retval, HashTable *symbol_table TSRMLS_DC, int param_count, ...)
{
- int i;
+ int i, l;
+ zval *arg;
+ zval *param;
+ unsigned char *arg_types;
zval **original_return_value;
HashTable *calling_symbol_table;
zend_function_state *original_function_state_ptr;
}
va_start(args, param_count);
- for (i=0; i<param_count; i++) {
- zval *arg;
- zval *param;
-
- arg = va_arg(args, zval*);
-
- if (EX(function_state).function->common.arg_types
- && i<EX(function_state).function->common.arg_types[0]
- && EX(function_state).function->common.arg_types[i+1]==BYREF_FORCE
- && !PZVAL_IS_REF(arg)) {
- if (arg->refcount > 1) {
- zval *new_zval;
-
- ALLOC_ZVAL(new_zval);
- *new_zval = *arg;
- zval_copy_ctor(new_zval);
- new_zval->refcount = 2;
- new_zval->is_ref = 1;
- arg->refcount--;
- param = new_zval;
- } else {
+ if (param_count) {
+ if ((arg_types = EX(function_state).function->common.arg_types) != NULL) {
+ l = arg_types[0];
+ } else {
+ l = 0;
+ }
+ for (i=1; i<=param_count; i++) {
+ arg = va_arg(args, zval*);
+
+ if (i<=l && arg_types[i]==BYREF_FORCE && !PZVAL_IS_REF(arg)) {
+ if (arg->refcount > 1) {
+ zval *new_zval;
+
+ ALLOC_ZVAL(new_zval);
+ *new_zval = *arg;
+ zval_copy_ctor(new_zval);
+ new_zval->refcount = 2;
+ new_zval->is_ref = 1;
+ arg->refcount--;
+ param = new_zval;
+ } else {
+ arg->refcount++;
+ arg->is_ref = 1;
+ param = arg;
+ }
+ } else if (arg != &EG(uninitialized_zval)) {
arg->refcount++;
- arg->is_ref = 1;
param = arg;
+ } else {
+ ALLOC_ZVAL(param);
+ *param = *arg;
+ INIT_PZVAL(param);
}
- } else if (arg != &EG(uninitialized_zval)) {
- arg->refcount++;
- param = arg;
- } else {
- ALLOC_ZVAL(param);
- *param = *arg;
- INIT_PZVAL(param);
+ zend_ptr_stack_push(&EG(argument_stack), param);
}
- zend_ptr_stack_push(&EG(argument_stack), param);
}
va_end(args);
}
/* }}} */
-/* {{{ spl_begin_method_call_this */
-static inline int spl_begin_method_call_this(zval **ce, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len, zval *retval TSRMLS_DC)
+/* {{{ spl_begin_method_call_no_retval */
+static inline int spl_begin_method_call_no_retval(zval **ce, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len TSRMLS_DC)
{
- zval *local_retval;
- int ret = spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, &local_retval, NULL TSRMLS_CC, 0);
- if (local_retval) {
- COPY_PZVAL_TO_ZVAL(*retval, local_retval);
- } else {
- INIT_ZVAL(*retval);
+ zval *retval;
+ int ret = spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, &retval, NULL TSRMLS_CC, 0);
+ if (retval) {
+ zval_dtor(retval);
+ FREE_ZVAL(retval);
}
return ret;
}
/* }}} */
-/* {{{ spl_begin_method_call_ex */
-static inline int spl_begin_method_call_ex(zval **ce, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len, zval **retval TSRMLS_DC)
-{
- return spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 0);
-}
-/* }}} */
+#define spl_begin_method_call_ex(ce, obj_ce, fn_proxy, function_name, fname_len, retval) \
+ spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 0)
-/* {{{ spl_begin_method_call_arg_ex1 */
-static inline int spl_begin_method_call_arg_ex1(zval **ce, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len, zval **retval, zval *arg1 TSRMLS_DC)
-{
- return spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 1, arg1);
-}
-/* }}} */
+#define spl_begin_method_call_arg_ex1(ce, obj_ce, fn_proxy, function_name, fname_len, retval, arg1) \
+ spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 1, arg1)
-/* {{{ spl_begin_method_call_arg_ex2 */
-static inline int spl_begin_method_call_arg_ex2(zval **ce, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len, zval **retval, zval *arg1, zval *arg2 TSRMLS_DC)
-{
- return spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 2, arg1, arg2);
-}
-/* }}} */
+#define spl_begin_method_call_arg_ex2(ce, obj_ce, fn_proxy, function_name, fname_len, retval, arg1, arg2) \
+ spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 2, arg1, arg2)
void spl_instanciate(zend_class_entry *pce, zval **object TSRMLS_DC);
int spl_instanciate_arg_ex2(zend_class_entry *pce, zval **retval, zval *arg1, zval *arg2, HashTable *symbol_table TSRMLS_DC);
{
zval **obj, *retval;
spl_foreach_proxy *proxy;
- zend_class_entry *instance_ce;
+ zend_class_entry *instance_ce, *obj_ce;
spl_is_a is_a;
+ temp_variable *tmp;
obj = spl_get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
if (is_a & SPL_IS_A_ITERATOR) {
spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
- spl_begin_method_call_ex(obj, NULL, NULL, "new_iterator", sizeof("new_iterator")-1, &retval TSRMLS_CC);
+ spl_begin_method_call_ex(obj, NULL, NULL, "new_iterator", sizeof("new_iterator")-1, &retval);
+ obj_ce = instance_ce;
instance_ce = spl_get_class_entry(retval TSRMLS_CC);
is_a = spl_implements(instance_ce);
if (!(is_a & SPL_IS_A_FORWARD)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Objects created by new_iterator() must implement spl_forward");
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Objects created by %s::new_iterator() must implement spl_forward", obj_ce->name);
ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_FE_RESET);
}
PZVAL_LOCK(retval);
retval->is_ref = 0;
retval->refcount = 2; /* lock two times */
/* return the created proxy container */
- EX_T(EX(opline)->result.u.var).var.ptr = retval;
- EX_T(EX(opline)->result.u.var).var.ptr_ptr = &EX_T(EX(opline)->result.u.var).var.ptr;
+ tmp = &EX_T(EX(opline)->result.u.var);
+ tmp->var.ptr = retval;
+ tmp->var.ptr_ptr = &tmp->var.ptr;
NEXT_OPCODE();
}
ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_FETCH)
{
znode *op1 = &EX(opline)->op1;
- zval **obj = spl_get_zval_ptr_ptr(op1, EX(Ts) TSRMLS_CC);
- zval more, tmp, *value, *key, *result;
+ zval **obj = spl_get_zval_ptr_ptr(op1, EX(Ts) TSRMLS_CC);
+ zval *more, *value, *key, *result;
spl_foreach_proxy *proxy;
if (Z_TYPE_PP(obj) == IS_STRING) {
obj = &proxy->obj; /* will be optimized out */
if (proxy->index++) {
- spl_begin_method_call_this(obj, proxy->obj_ce, &proxy->funcs.next, "next", sizeof("next")-1, &tmp TSRMLS_CC);
+ spl_begin_method_call_no_retval(obj, proxy->obj_ce, &proxy->funcs.next, "next", sizeof("next")-1 TSRMLS_CC);
} else {
if (proxy->is_a & SPL_IS_A_SEQUENCE) {
- spl_begin_method_call_this(obj, proxy->obj_ce, &proxy->funcs.rewind, "rewind", sizeof("rewind")-1, &tmp TSRMLS_CC);
+ spl_begin_method_call_no_retval(obj, proxy->obj_ce, &proxy->funcs.rewind, "rewind", sizeof("rewind")-1 TSRMLS_CC);
}
op_array->opcodes[EX(opline)->op2.u.opline_num].op2 = *op1;
}
- spl_begin_method_call_this(obj, proxy->obj_ce, &proxy->funcs.more, "has_more", sizeof("has_more")-1, &more TSRMLS_CC);
- if (zend_is_true(&more)) {
+ spl_begin_method_call_ex(obj, proxy->obj_ce, &proxy->funcs.more, "has_more", sizeof("has_more")-1, &more);
+ if (!more->type == IS_BOOL && !more->type == IS_LONG) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Method %s::has_more implements spl_forward::has_more and should return a value of type boolean or int");
+ convert_to_boolean(more);
+ }
+ if (more->value.lval) {
+ zval_dtor(more);
+ FREE_ZVAL(more);
result = &EX_T(EX(opline)->result.u.var).tmp_var;
- spl_begin_method_call_ex(obj, proxy->obj_ce, &proxy->funcs.current, "current", sizeof("current")-1, &value TSRMLS_CC);
+ spl_begin_method_call_ex(obj, proxy->obj_ce, &proxy->funcs.current, "current", sizeof("current")-1, &value);
if (proxy->is_a & SPL_IS_A_ASSOC) {
- spl_begin_method_call_ex(obj, proxy->obj_ce, &proxy->funcs.key, "key", sizeof("key")-1, &key TSRMLS_CC);
+ spl_begin_method_call_ex(obj, proxy->obj_ce, &proxy->funcs.key, "key", sizeof("key")-1, &key);
} else {
MAKE_STD_ZVAL(key);
key->value.lval = proxy->index;
}
#ifndef OPTIMIZED_ARRAY_CONSTRUCT
array_init(result);
- zend_hash_index_update(result->value.ht, 0, &value, sizeof(zval *), NULL);
- zend_hash_index_update(result->value.ht, 1, &key, sizeof(zval *), NULL);
+ add_next_index_zval(result, value);
+ add_next_index_zval(result, key);
#else
{
Bucket *p;
#endif
NEXT_OPCODE();
}
+ zval_dtor(more);
+ FREE_ZVAL(more);
EX(opline) = op_array->opcodes+EX(opline)->op2.u.opline_num;
return 0;
}
void spl_register_std_class(zend_class_entry ** ppce, char * class_name, void * obj_ctor TSRMLS_DC)
{
zend_class_entry ce;
- memset(&ce, 0, sizeof(zend_class_entry));
INIT_CLASS_ENTRY(ce, class_name, NULL);
ce.name_length = strlen(class_name);
}
/* }}} */
-/* {{ spl_make_fully_qualyfied_name */
-char * spl_make_fully_qualyfied_name(zend_class_entry * pce TSRMLS_DC)
-{
- return estrdup(pce->name);
-}
-/* }}} */
-
/* {{{ spl_add_class_name */
void spl_add_class_name(zval * list, zend_class_entry * pce TSRMLS_DC)
{
- char * str = spl_make_fully_qualyfied_name(pce TSRMLS_CC);
- size_t len = strlen(str);
+ size_t len = strlen(pce->name);
zval *tmp;
- if (zend_hash_find(Z_ARRVAL_P(list), str, len+1, (void*)&tmp) == FAILURE) {
+ if (zend_hash_find(Z_ARRVAL_P(list), pce->name, len+1, (void*)&tmp) == FAILURE) {
MAKE_STD_ZVAL(tmp);
- ZVAL_STRING(tmp, str, 0);
- zend_hash_add(Z_ARRVAL_P(list), str, len+1, &tmp, sizeof(zval *), NULL);
- } else {
- efree(str);
+ ZVAL_STRING(tmp, pce->name, 1);
+ zend_hash_add(Z_ARRVAL_P(list), pce->name, len+1, &tmp, sizeof(zval *), NULL);
}
}
/* }}} */
typedef zend_object_value (*create_object_func_t)(zend_class_entry *class_type TSRMLS_DC);
-#define REGISTER_SPL_STD_CLASS(namespace_name, class_name, obj_ctor) \
+#define REGISTER_SPL_STD_CLASS(class_name, obj_ctor) \
spl_register_std_class(&spl_ce_ ## class_name, "spl_" # class_name, obj_ctor TSRMLS_CC);
-#define REGISTER_SPL_INTERFACE(namespace_name, class_name) \
+#define REGISTER_SPL_INTERFACE(class_name) \
spl_register_interface(&spl_ce_ ## class_name, "spl_" # class_name TSRMLS_CC);
-#define REGISTER_SPL_INTF_FUNC(namespace_name, class_name, function_name) \
+#define REGISTER_SPL_INTF_FUNC(class_name, function_name) \
spl_register_interface_function(spl_ce_ ## class_name, # function_name TSRMLS_CC);
-#define REGISTER_SPL_PARENT_CE(namespace_name, class_name, parent_class) \
+#define REGISTER_SPL_PARENT_CE(class_name, parent_class) \
spl_register_parent_ce(spl_ce_ ## class_name, spl_ce_ ## parent_class TSRMLS_CC);
-#define REGISTER_SPL_IMPLEMENT(namespace_name, class_name, interface_name) \
+#define REGISTER_SPL_IMPLEMENT(class_name, interface_name) \
spl_register_implement(spl_ce_ ## class_name, spl_ce_ ## interface_name TSRMLS_CC);
-#define REGISTER_SPL_FUNCTIONS(namespace_name, class_name, function_list) \
+#define REGISTER_SPL_FUNCTIONS(class_name, function_list) \
spl_register_functions(spl_ce_ ## class_name, function_list TSRMLS_CC);
void spl_destroy_class(zend_class_entry ** ppce);
void spl_register_implement(zend_class_entry * class_entry, zend_class_entry * interface_entry TSRMLS_DC);
void spl_register_functions(zend_class_entry * class_entry, function_entry * function_list TSRMLS_DC);
-char * spl_make_fully_qualyfied_name(zend_class_entry * pce TSRMLS_DC);
void spl_add_class_name(zval * list, zend_class_entry * pce TSRMLS_DC);
void spl_add_interfaces(zval * list, zend_class_entry * pce TSRMLS_DC);
int spl_add_classes(zend_class_entry ** ppce, zval *list TSRMLS_DC);
$i = new c();
-$c_info = array(class_name($i) => array('inheits' => class_parents($i), 'implements' => class_implements($i)));
+$c_info = array(get_class($i) => array('inheits' => class_parents($i), 'implements' => class_implements($i)));
print_r($c_info);
$methods = get_class_methods("spl_forward_assoc");
sort($methods);
$t = new c();
$i = $t->new_iterator();
-$c_info = array(class_name($t) => array('inheits' => class_parents($t), 'implements' => class_implements($t)),
- class_name($i) => array('inheits' => class_parents($i), 'implements' => class_implements($i)));
+$c_info = array(get_class($t) => array('inheits' => class_parents($t), 'implements' => class_implements($t)),
+ get_class($i) => array('inheits' => class_parents($i), 'implements' => class_implements($i)));
print_r($c_info);
foreach($i as $w) {