Surprisingly, It can be done quite easily with the current object
handler infrastructure.
Moriyoshi
On Sun, Mar 14, 2010 at 12:08 AM, Pierre Joye <pierre.php@gmail.com> wrote:
> On Sat, Mar 13, 2010 at 3:13 PM, Moriyoshi Koizumi <mozo@mozo.jp> wrote:
>
>> I don't totally agree with what is being said here, but I guess we
>> don't have to make Unicode a first-class value. Once operator
>> overloading is supported, Unicode strings can be represented as
>> objects, like Python does although I didn't have a look at past
>> discussion on this topic.
>
> Operators overloading, while being a cool feature, should not be
> associated with Unicode&related features. Or we are going to do the
> exact same mistakes than before, way too many changes, features, work
> to even get a visible deadline for the next major release.
>
> Cheers,
> --
> Pierre
>
> @pierrejoye | http://blog.thepimp.net | http://www.libgd.org
>
diff --git a/Zend/zend.h b/Zend/zend.h
index 38f461c..0ffcb1a 100644
--- a/Zend/zend.h
+++ b/Zend/zend.h
@@ -442,6 +442,7 @@ struct _zend_class_entry {
union _zend_function *__call;
union _zend_function *__callstatic;
union _zend_function *__tostring;
+ union _zend_function *__concat;
union _zend_function *serialize_func;
union _zend_function *unserialize_func;
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 5433dc1..e0dcd73 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -1799,7 +1799,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
int count=0, unload=0;
HashTable *target_function_table = function_table;
int error_type;
- zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL;
+ zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL, *__concat = NULL;
char *lowercase_name;
int fname_len;
char *lc_class_name = NULL;
@@ -1929,6 +1929,8 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
__unset = reg_function;
} else if ((fname_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME))) {
__isset = reg_function;
+ } else if ((fname_len == sizeof(ZEND_CONCAT_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CONCAT_FUNC_NAME, sizeof(ZEND_CONCAT_FUNC_NAME))) {
+ __concat = reg_function;
} else {
reg_function = NULL;
}
@@ -1967,6 +1969,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
scope->__set = __set;
scope->__unset = __unset;
scope->__isset = __isset;
+ scope->__concat = __concat;
if (ctor) {
ctor->common.fn_flags |= ZEND_ACC_CTOR;
if (ctor->common.fn_flags & ZEND_ACC_STATIC) {
@@ -2030,6 +2033,12 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
}
__isset->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
}
+ if (__concat) {
+ if (__concat->common.fn_flags & ZEND_ACC_STATIC) {
+ zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __concat->common.function_name);
+ }
+ __concat->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
+ }
efree(lc_class_name);
}
return SUCCESS;
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 13b6c55..91cd34a 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -1267,6 +1267,10 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
} else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1))) {
if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static");
+ }
+ } else if ((name_len == sizeof(ZEND_CONCAT_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CONCAT_FUNC_NAME, sizeof(ZEND_CONCAT_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_WARNING, "The magic method " ZEND_CONCAT_FUNC_NAME " must have public visibility and cannot be static");
}
}
} else {
@@ -1335,6 +1339,11 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static");
}
CG(active_class_entry)->__tostring = (zend_function *) CG(active_op_array);
+ } else if ((name_len == sizeof(ZEND_CONCAT_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CONCAT_FUNC_NAME, sizeof(ZEND_CONCAT_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_WARNING, "The magic method " ZEND_CONCAT_FUNC_NAME " must have public visibility and cannot be static");
+ }
+ CG(active_class_entry)->__concat = (zend_function *) CG(active_op_array);
} else if (!(fn_flags & ZEND_ACC_STATIC)) {
CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC;
}
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index faff1ec..0656883 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -745,6 +745,7 @@ END_EXTERN_C()
#define ZEND_CALLSTATIC_FUNC_NAME "__callstatic"
#define ZEND_TOSTRING_FUNC_NAME "__tostring"
#define ZEND_AUTOLOAD_FUNC_NAME "__autoload"
+#define ZEND_CONCAT_FUNC_NAME "__concat"
/* The following constants may be combined in CG(compiler_options)
* to change the default compiler behavior */