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