mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Implemented builtin instruction for strlen()
This commit is contained in:
parent
42c4bcaed1
commit
af7cb16907
8 changed files with 102 additions and 6 deletions
|
@ -2799,6 +2799,36 @@ static int zend_do_convert_type_check(zend_op *init_opline, znode *result, zend_
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static int zend_do_convert_defined(zend_op *init_opline, znode *result TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval c;
|
||||
zend_string *lc_name;
|
||||
zend_op *opline = init_opline + 1;
|
||||
|
||||
if (opline->opcode != ZEND_SEND_VAL ||
|
||||
opline->op1_type != IS_CONST ||
|
||||
Z_TYPE(CONSTANT(opline->op1.constant)) != IS_STRING
|
||||
|| zend_memrchr(Z_STRVAL(CONSTANT(opline->op1.constant)), '\\', Z_STRLEN(CONSTANT(opline->op1.constant))) != NULL
|
||||
|| zend_memrchr(Z_STRVAL(CONSTANT(opline->op1.constant)), ':', Z_STRLEN(CONSTANT(opline->op1.constant))) != NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MAKE_NOP(init_opline);
|
||||
opline->opcode = ZEND_DEFINED;
|
||||
opline->extended_value = 0;
|
||||
GET_CACHE_SLOT(opline->op1.constant);
|
||||
/* lowcase constant name */
|
||||
lc_name = STR_ALLOC(Z_STRLEN(CONSTANT(opline->op1.constant)), 0);
|
||||
zend_str_tolower_copy(lc_name->val, Z_STRVAL(CONSTANT(opline->op1.constant)), Z_STRLEN(CONSTANT(opline->op1.constant)));
|
||||
ZVAL_NEW_STR(&c, lc_name);
|
||||
zend_add_literal(CG(active_op_array), &c);
|
||||
opline->result.var = get_temporary_variable(CG(active_op_array));
|
||||
opline->result_type = IS_TMP_VAR;
|
||||
GET_NODE(result, opline->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;
|
||||
|
@ -2836,6 +2866,14 @@ void zend_do_end_function_call(znode *function_name, znode *result, int is_metho
|
|||
fcall->arg_num = 0;
|
||||
}
|
||||
}
|
||||
} else if (func->common.function_name->len == sizeof("defined")-1 &&
|
||||
memcmp(func->common.function_name->val, "defined", sizeof("defined")-1) == 0) {
|
||||
if (fcall->arg_num == 1) {
|
||||
if (zend_do_convert_defined(opline, result TSRMLS_CC)) {
|
||||
zend_stack_del_top(&CG(function_call_stack));
|
||||
return;
|
||||
}
|
||||
}
|
||||
} 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) {
|
||||
|
|
|
@ -5935,4 +5935,24 @@ ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY)
|
|||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *name;
|
||||
zend_constant *c;
|
||||
|
||||
SAVE_OPLINE();
|
||||
name = GET_OP1_ZVAL_PTR(BP_VAR_R);
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
|
||||
ZVAL_TRUE(EX_VAR(opline->result.var));
|
||||
} else if ((c = zend_quick_get_constant(opline->op1.zv, 0 TSRMLS_CC)) == NULL) {
|
||||
ZVAL_FALSE(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), c);
|
||||
ZVAL_TRUE(EX_VAR(opline->result.var));
|
||||
}
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_EXPORT_HANDLER(zend_do_fcall, ZEND_DO_FCALL)
|
||||
|
|
|
@ -3450,6 +3450,26 @@ static int ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER
|
|||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *name;
|
||||
zend_constant *c;
|
||||
|
||||
SAVE_OPLINE();
|
||||
name = opline->op1.zv;
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
|
||||
ZVAL_TRUE(EX_VAR(opline->result.var));
|
||||
} else if ((c = zend_quick_get_constant(opline->op1.zv, 0 TSRMLS_CC)) == NULL) {
|
||||
ZVAL_FALSE(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), c);
|
||||
ZVAL_TRUE(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
|
||||
|
@ -44000,11 +44020,11 @@ void zend_init_opcodes_handlers(void)
|
|||
ZEND_STRLEN_SPEC_CV_HANDLER,
|
||||
ZEND_STRLEN_SPEC_CV_HANDLER,
|
||||
ZEND_STRLEN_SPEC_CV_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_DEFINED_SPEC_CONST_HANDLER,
|
||||
ZEND_DEFINED_SPEC_CONST_HANDLER,
|
||||
ZEND_DEFINED_SPEC_CONST_HANDLER,
|
||||
ZEND_DEFINED_SPEC_CONST_HANDLER,
|
||||
ZEND_DEFINED_SPEC_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
|
|
|
@ -144,7 +144,7 @@ const char *zend_vm_opcodes_map[169] = {
|
|||
"ZEND_SEND_ARRAY",
|
||||
"ZEND_SEND_USER",
|
||||
"ZEND_STRLEN",
|
||||
NULL,
|
||||
"ZEND_DEFINED",
|
||||
"ZEND_TYPE_CHECK",
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -145,6 +145,7 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);
|
|||
#define ZEND_SEND_ARRAY 119
|
||||
#define ZEND_SEND_USER 120
|
||||
#define ZEND_STRLEN 121
|
||||
#define ZEND_DEFINED 122
|
||||
#define ZEND_TYPE_CHECK 123
|
||||
#define ZEND_PRE_INC_OBJ 132
|
||||
#define ZEND_PRE_DEC_OBJ 133
|
||||
|
|
|
@ -147,6 +147,9 @@ static void optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_c
|
|||
case ZEND_CATCH:
|
||||
LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2);
|
||||
break;
|
||||
case ZEND_DEFINED:
|
||||
LITERAL_INFO(opline->op1.constant, LITERAL_CONST, 1, 1, 2);
|
||||
break;
|
||||
case ZEND_FETCH_CONSTANT:
|
||||
if (ZEND_OP1_TYPE(opline) == IS_UNUSED) {
|
||||
if ((opline->extended_value & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) {
|
||||
|
|
|
@ -468,6 +468,19 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
|
|||
MAKE_NOP(opline);
|
||||
}
|
||||
break;
|
||||
case ZEND_DEFINED:
|
||||
{
|
||||
zval c;
|
||||
zend_uint tv = ZEND_RESULT(opline).var;
|
||||
if (!zend_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline)), &c, 0 TSRMLS_CC)) {
|
||||
break;
|
||||
}
|
||||
ZVAL_TRUE(&c);
|
||||
replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC);
|
||||
literal_dtor(&ZEND_OP1_LITERAL(opline));
|
||||
MAKE_NOP(opline);
|
||||
}
|
||||
break;
|
||||
#if ZEND_EXTENSION_API_NO > PHP_5_2_X_API_NO
|
||||
case ZEND_DECLARE_CONST:
|
||||
if (collect_constants &&
|
||||
|
|
|
@ -171,6 +171,7 @@ static void update_op1_const(zend_op_array *op_array,
|
|||
case ZEND_INIT_STATIC_METHOD_CALL:
|
||||
case ZEND_CATCH:
|
||||
case ZEND_FETCH_CONSTANT:
|
||||
case ZEND_DEFINED:
|
||||
opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
|
||||
STR_HASH_VAL(Z_STR(ZEND_OP1_LITERAL(opline)));
|
||||
Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->last_cache_slot++;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue