}
/* }}} */
+static int zend_do_convert_strlen(zend_op *init_opline, znode *result TSRMLS_DC) /* {{{ */
+{
+ zend_op *opline = init_opline + 1;
+ zend_op *send = NULL;
+ int level = 0;
+
+ do {
+ switch (opline->opcode) {
+ case ZEND_SEND_VAL:
+ case ZEND_SEND_VAL_EX:
+ case ZEND_SEND_VAR:
+ case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_VAR_NO_REF:
+ case ZEND_SEND_REF:
+ case ZEND_SEND_UNPACK:
+ if (level == 0) {
+ if (opline->opcode == ZEND_SEND_UNPACK) {
+ return 0;
+ }
+ send = opline;
+ }
+ break;
+ case ZEND_INIT_FCALL_BY_NAME:
+ case ZEND_INIT_NS_FCALL_BY_NAME:
+ case ZEND_NEW:
+ case ZEND_INIT_METHOD_CALL:
+ case ZEND_INIT_STATIC_METHOD_CALL:
+ case ZEND_INIT_FCALL:
+ level++;
+ break;
+ case ZEND_DO_FCALL:
+ level--;
+ break;
+ }
+ opline++;
+ } while (send == NULL);
+
+ MAKE_NOP(init_opline);
+ send->opcode = ZEND_STRLEN;
+ send->extended_value = 0;
+ SET_UNUSED(send->op2);
+ send->result.var = get_temporary_variable(CG(active_op_array));
+ send->result_type = IS_TMP_VAR;
+ GET_NODE(result, send->result);
+ return 1;
+}
+/* }}} */
+
void zend_do_end_function_call(znode *function_name, znode *result, int is_method, int is_dynamic_fcall TSRMLS_DC) /* {{{ */
{
zend_op *opline;
fcall->arg_num = 0;
}
}
+ } else if ((CG(compiler_options) & ZEND_COMPILE_NO_BUILTIN_STRLEN) == 0 &&
+ func->common.function_name->len == sizeof("strlen")-1 &&
+ memcmp(func->common.function_name->val, "strlen", sizeof("strlen")-1) == 0) {
+ if (fcall->arg_num == 1) {
+ if (zend_do_convert_strlen(opline, result TSRMLS_CC)) {
+ zend_stack_del_top(&CG(function_call_stack));
+ return;
+ }
+ }
}
}
}
"Cannot use positional argument after argument unpacking");
}
+ if (op == ZEND_SEND_VAR && (param->op_type & (IS_CONST|IS_TMP_VAR))) {
+ /* Function call was converted into builtin instruction */
+ zend_llist *fetch_list_ptr = zend_stack_top(&CG(bp_stack));
+ zend_llist_destroy(fetch_list_ptr);
+ zend_stack_del_top(&CG(bp_stack));
+ original_op = op = ZEND_SEND_VAL;
+ }
+
if (original_op == ZEND_SEND_REF) {
if (function_ptr &&
function_ptr->common.function_name &&
ZEND_VM_NEXT_OPCODE();
}
+ZEND_VM_HANDLER(121, ZEND_STRLEN, CONST|TMP|VAR|CV, ANY)
+{
+ USE_OPLINE
+ zval *value;
+ zend_free_op free_op1;
+
+ SAVE_OPLINE();
+ value = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+ ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
+ } else {
+ if (Z_TYPE_P(value) < IS_TRUE) {
+ ZVAL_LONG(EX_VAR(opline->result.var), 0);
+ } else if (Z_TYPE_P(value) == IS_TRUE) {
+ ZVAL_LONG(EX_VAR(opline->result.var), 1);
+ } else if (Z_TYPE_P(value) <= IS_DOUBLE) {
+ zend_string *str = zval_get_string(value);
+ ZVAL_LONG(EX_VAR(opline->result.var), str->len);
+ STR_RELEASE(str);
+ } else if (Z_TYPE_P(value) == IS_OBJECT) {
+ zend_string *str;
+
+ if (parse_arg_object_to_str(value, &str, IS_STRING TSRMLS_CC) == FAILURE) {
+ ZEND_VM_C_GOTO(strlen_error);
+ }
+ ZVAL_LONG(EX_VAR(opline->result.var), str->len);
+ STR_RELEASE(str);
+ } else {
+ZEND_VM_C_LABEL(strlen_error):
+ zend_error(E_WARNING, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ }
+ FREE_OP1();
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
ZEND_VM_EXPORT_HANDLER(zend_do_fcall, ZEND_DO_FCALL)
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_STRLEN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval *value;
+
+
+ SAVE_OPLINE();
+ value = opline->op1.zv;
+ if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+ ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
+ } else {
+ if (Z_TYPE_P(value) < IS_TRUE) {
+ ZVAL_LONG(EX_VAR(opline->result.var), 0);
+ } else if (Z_TYPE_P(value) == IS_TRUE) {
+ ZVAL_LONG(EX_VAR(opline->result.var), 1);
+ } else if (Z_TYPE_P(value) <= IS_DOUBLE) {
+ zend_string *str = zval_get_string(value);
+ ZVAL_LONG(EX_VAR(opline->result.var), str->len);
+ STR_RELEASE(str);
+ } else if (Z_TYPE_P(value) == IS_OBJECT) {
+ zend_string *str;
+
+ if (parse_arg_object_to_str(value, &str, IS_STRING TSRMLS_CC) == FAILURE) {
+ goto strlen_error;
+ }
+ ZVAL_LONG(EX_VAR(opline->result.var), str->len);
+ STR_RELEASE(str);
+ } else {
+strlen_error:
+ zend_error(E_WARNING, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ }
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_STRLEN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval *value;
+ zend_free_op free_op1;
+
+ SAVE_OPLINE();
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+ ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
+ } else {
+ if (Z_TYPE_P(value) < IS_TRUE) {
+ ZVAL_LONG(EX_VAR(opline->result.var), 0);
+ } else if (Z_TYPE_P(value) == IS_TRUE) {
+ ZVAL_LONG(EX_VAR(opline->result.var), 1);
+ } else if (Z_TYPE_P(value) <= IS_DOUBLE) {
+ zend_string *str = zval_get_string(value);
+ ZVAL_LONG(EX_VAR(opline->result.var), str->len);
+ STR_RELEASE(str);
+ } else if (Z_TYPE_P(value) == IS_OBJECT) {
+ zend_string *str;
+
+ if (parse_arg_object_to_str(value, &str, IS_STRING TSRMLS_CC) == FAILURE) {
+ goto strlen_error;
+ }
+ ZVAL_LONG(EX_VAR(opline->result.var), str->len);
+ STR_RELEASE(str);
+ } else {
+strlen_error:
+ zend_error(E_WARNING, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ }
+ zval_dtor(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_STRLEN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval *value;
+ zend_free_op free_op1;
+
+ SAVE_OPLINE();
+ value = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+ ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
+ } else {
+ if (Z_TYPE_P(value) < IS_TRUE) {
+ ZVAL_LONG(EX_VAR(opline->result.var), 0);
+ } else if (Z_TYPE_P(value) == IS_TRUE) {
+ ZVAL_LONG(EX_VAR(opline->result.var), 1);
+ } else if (Z_TYPE_P(value) <= IS_DOUBLE) {
+ zend_string *str = zval_get_string(value);
+ ZVAL_LONG(EX_VAR(opline->result.var), str->len);
+ STR_RELEASE(str);
+ } else if (Z_TYPE_P(value) == IS_OBJECT) {
+ zend_string *str;
+
+ if (parse_arg_object_to_str(value, &str, IS_STRING TSRMLS_CC) == FAILURE) {
+ goto strlen_error;
+ }
+ ZVAL_LONG(EX_VAR(opline->result.var), str->len);
+ STR_RELEASE(str);
+ } else {
+strlen_error:
+ zend_error(E_WARNING, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ }
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval *value;
+
+
+ SAVE_OPLINE();
+ value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+ ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
+ } else {
+ if (Z_TYPE_P(value) < IS_TRUE) {
+ ZVAL_LONG(EX_VAR(opline->result.var), 0);
+ } else if (Z_TYPE_P(value) == IS_TRUE) {
+ ZVAL_LONG(EX_VAR(opline->result.var), 1);
+ } else if (Z_TYPE_P(value) <= IS_DOUBLE) {
+ zend_string *str = zval_get_string(value);
+ ZVAL_LONG(EX_VAR(opline->result.var), str->len);
+ STR_RELEASE(str);
+ } else if (Z_TYPE_P(value) == IS_OBJECT) {
+ zend_string *str;
+
+ if (parse_arg_object_to_str(value, &str, IS_STRING TSRMLS_CC) == FAILURE) {
+ goto strlen_error;
+ }
+ ZVAL_LONG(EX_VAR(opline->result.var), str->len);
+ STR_RELEASE(str);
+ } else {
+strlen_error:
+ zend_error(E_WARNING, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value)));
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ }
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
ZEND_SEND_USER_SPEC_CV_HANDLER,
ZEND_SEND_USER_SPEC_CV_HANDLER,
ZEND_SEND_USER_SPEC_CV_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
+ ZEND_STRLEN_SPEC_CONST_HANDLER,
+ ZEND_STRLEN_SPEC_CONST_HANDLER,
+ ZEND_STRLEN_SPEC_CONST_HANDLER,
+ ZEND_STRLEN_SPEC_CONST_HANDLER,
+ ZEND_STRLEN_SPEC_CONST_HANDLER,
+ ZEND_STRLEN_SPEC_TMP_HANDLER,
+ ZEND_STRLEN_SPEC_TMP_HANDLER,
+ ZEND_STRLEN_SPEC_TMP_HANDLER,
+ ZEND_STRLEN_SPEC_TMP_HANDLER,
+ ZEND_STRLEN_SPEC_TMP_HANDLER,
+ ZEND_STRLEN_SPEC_VAR_HANDLER,
+ ZEND_STRLEN_SPEC_VAR_HANDLER,
+ ZEND_STRLEN_SPEC_VAR_HANDLER,
+ ZEND_STRLEN_SPEC_VAR_HANDLER,
+ ZEND_STRLEN_SPEC_VAR_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_STRLEN_SPEC_CV_HANDLER,
+ ZEND_STRLEN_SPEC_CV_HANDLER,
+ ZEND_STRLEN_SPEC_CV_HANDLER,
+ ZEND_STRLEN_SPEC_CV_HANDLER,
+ ZEND_STRLEN_SPEC_CV_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,