I've made a small patch that turns strlen() into a statement executed by
the engine instead of a function. The reasoning is that something that
integral should probably be in the engine. I haven't done hard
benchmarking but it seems to improve performance of that particular
piece of code by about 25%. Feedback is welcome.

-Andrei                                       http://www.gravitonic.com/
* "UNIX, isn't that some archaic form of DOS?" - our job applicant *
Index: zend_builtin_functions.c
===================================================================
RCS file: /repository/Zend/zend_builtin_functions.c,v
retrieving revision 1.124
diff -u -2 -b -w -B -r1.124 zend_builtin_functions.c
--- zend_builtin_functions.c    21 Oct 2002 08:42:32 -0000      1.124
+++ zend_builtin_functions.c    8 Nov 2002 21:15:20 -0000
@@ -30,5 +30,4 @@
 static ZEND_FUNCTION(func_get_arg);
 static ZEND_FUNCTION(func_get_args);
-static ZEND_NAMED_FUNCTION(zend_if_strlen);
 static ZEND_FUNCTION(strcmp);
 static ZEND_FUNCTION(strncmp);
@@ -80,5 +79,4 @@
        ZEND_FE(func_get_arg,           NULL)
        ZEND_FE(func_get_args,          NULL)
-       { "strlen", zend_if_strlen, NULL },
        ZEND_FE(strcmp,                         NULL)
        ZEND_FE(strncmp,                        NULL)
@@ -244,19 +242,4 @@
                zend_hash_next_index_insert(return_value->value.ht, &element, 
sizeof(zval *), NULL);
        }
-}
-/* }}} */
-
-
-/* {{{ proto int strlen(string str)
-   Get string length */
-ZEND_NAMED_FUNCTION(zend_if_strlen)
-{
-       zval **str;
-       
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) {
-               ZEND_WRONG_PARAM_COUNT();
-       }
-       convert_to_string_ex(str);
-       RETVAL_LONG((*str)->value.str.len);
 }
 /* }}} */
Index: zend_compile.c
===================================================================
RCS file: /repository/Zend/zend_compile.c,v
retrieving revision 1.239
diff -u -2 -b -w -B -r1.239 zend_compile.c
--- zend_compile.c      3 Nov 2002 15:16:44 -0000       1.239
+++ zend_compile.c      8 Nov 2002 21:15:21 -0000
@@ -2101,4 +2101,15 @@
 }
 
+void zend_do_strlen(znode *result, znode *expr TSRMLS_DC)
+{
+       zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+       opline->opcode = ZEND_STRLEN;
+       opline->result.op_type = IS_TMP_VAR;
+       opline->result.u.var = get_temporary_variable(CG(active_op_array));
+       opline->op1 = *expr;
+       SET_UNUSED(opline->op2);
+       *result = opline->result;
+}
 
 void zend_do_foreach_begin(znode *foreach_token, znode *array, znode 
*open_brackets_token, znode *as_token, int variable TSRMLS_DC)
Index: zend_compile.h
===================================================================
RCS file: /repository/Zend/zend_compile.h,v
retrieving revision 1.144
diff -u -2 -b -w -B -r1.144 zend_compile.h
--- zend_compile.h      4 Aug 2002 06:39:44 -0000       1.144
+++ zend_compile.h      8 Nov 2002 21:15:21 -0000
@@ -326,4 +326,6 @@
 void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC);
 
+void zend_do_strlen(znode *result, znode *expr TSRMLS_DC);
+
 void zend_do_foreach_begin(znode *foreach_token, znode *array, znode 
*open_brackets_token, znode *as_token, int variable TSRMLS_DC);
 void zend_do_foreach_cont(znode *value, znode *key, znode *as_token TSRMLS_DC);
@@ -522,4 +524,6 @@
 
 #define ZEND_SEND_VAR_NO_REF           106
+
+#define ZEND_STRLEN                 107
 
 /* end of block */
Index: zend_execute.c
===================================================================
RCS file: /repository/Zend/zend_execute.c,v
retrieving revision 1.315
diff -u -2 -b -w -B -r1.315 zend_execute.c
--- zend_execute.c      3 Nov 2002 15:16:45 -0000       1.315
+++ zend_execute.c      8 Nov 2002 21:15:21 -0000
@@ -2360,4 +2360,20 @@
                                }
                                NEXT_OPCODE();
+                       case ZEND_STRLEN: {
+                                       zval tmp_val, *val = 
+get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
+                                       if (val->type != IS_STRING) {
+                                               tmp_val = *val;
+                                               zval_copy_ctor(&tmp_val);
+                                               convert_to_string(&tmp_val);
+                                               val = &tmp_val;
+                                       }
+                                       
+EX(Ts)[EX(opline)->result.u.var].tmp_var.value.lval = val->value.str.len;
+                                       EX(Ts)[EX(opline)->result.u.var].tmp_var.type 
+= IS_LONG;
+                                       if (val == &tmp_val) {
+                                               zval_dtor(&tmp_val);
+                                       }
+                                       FREE_OP(EX(Ts), &EX(opline)->op1, 
+EG(free_op1));
+                               }
+                               NEXT_OPCODE();
                        case ZEND_ISSET_ISEMPTY: {
                                        zval **var = 
get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_IS);
Index: zend_language_parser.y
===================================================================
RCS file: /repository/Zend/zend_language_parser.y,v
retrieving revision 1.23
diff -u -2 -b -w -B -r1.23 zend_language_parser.y
--- zend_language_parser.y      4 Aug 2002 06:39:44 -0000       1.23
+++ zend_language_parser.y      8 Nov 2002 21:15:22 -0000
@@ -113,4 +113,5 @@
 %token T_ISSET
 %token T_EMPTY
+%token T_STRLEN
 %token T_CLASS
 %token T_EXTENDS
@@ -712,4 +713,5 @@
                T_ISSET '(' isset_variables ')' { $$ = $3; }
        |       T_EMPTY '(' cvar ')'    { zend_do_isset_or_isempty(ZEND_ISEMPTY, &$$, 
&$3 TSRMLS_CC); }
+    |   T_STRLEN '(' expr ')'   { zend_do_strlen(&$$, &$3 TSRMLS_CC); }
        |       T_INCLUDE expr                  { 
zend_do_include_or_eval(ZEND_INCLUDE, &$$, &$2 TSRMLS_CC); }
        |       T_INCLUDE_ONCE expr     { zend_do_include_or_eval(ZEND_INCLUDE_ONCE, 
&$$, &$2 TSRMLS_CC); }
Index: zend_language_scanner.l
===================================================================
RCS file: /repository/Zend/zend_language_scanner.l,v
retrieving revision 1.53
diff -u -2 -b -w -B -r1.53 zend_language_scanner.l
--- zend_language_scanner.l     8 Nov 2002 13:40:54 -0000       1.53
+++ zend_language_scanner.l     8 Nov 2002 21:15:22 -0000
@@ -926,4 +926,8 @@
 }
 
+<ST_IN_SCRIPTING>"strlen" {
+       return T_STRLEN;
+}
+
 <ST_IN_SCRIPTING>"=>" {
        return T_DOUBLE_ARROW;

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to