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