From: Dmitry Stogov Date: Wed, 24 May 2017 20:00:48 +0000 (+0300) Subject: Added ZEND_IN_ARRAY instruction, implementing optimized in_array() builtin function... X-Git-Tag: php-7.2.0alpha1~57^2~35 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7c7383067f6719324004407e17c0f5d6c740c39f;p=php Added ZEND_IN_ARRAY instruction, implementing optimized in_array() builtin function, through hash lookup in flipped array --- diff --git a/NEWS b/NEWS index c231f50eda..483de90cab 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ PHP NEWS ?? ??? ????, PHP 7.2 - Core: + . Added ZEND_IN_ARRAY instruction, implementing optimized in_array() builtin + function, through hash lookup in flipped array. (Dmitry) . Removed IS_TYPE_IMMUTABLE (it's the same as COPYABLE & !REFCOUNTED). (Dmitry) . Removed the sql.safe_mode directive. (Kalle) . Removed support for Netware. (Kalle) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 22c6ca114c..a35e2acc7b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -87,6 +87,7 @@ ZEND_API zend_executor_globals executor_globals; #endif static zend_op *zend_emit_op(znode *result, zend_uchar opcode, znode *op1, znode *op2); +static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast); static void zend_destroy_property_info_internal(zval *zv) /* {{{ */ { @@ -2224,6 +2225,7 @@ ZEND_API int zend_is_smart_branch(zend_op *opline) /* {{{ */ case ZEND_INSTANCEOF: case ZEND_TYPE_CHECK: case ZEND_DEFINED: + case ZEND_IN_ARRAY: return 1; default: return 0; @@ -3635,6 +3637,76 @@ static int zend_compile_assert(znode *result, zend_ast_list *args, zend_string * } /* }}} */ +static int zend_compile_func_in_array(znode *result, zend_ast_list *args) /* {{{ */ +{ + zend_bool strict = 0; + znode array, needly; + zend_op *opline; + + if (args->children == 3) { + if (args->child[2]->kind != ZEND_AST_ZVAL) { + return FAILURE; + } + strict = zend_is_true(zend_ast_get_zval(args->child[2])); + } + + if (args->children < 2 + || args->children > 3 + || args->child[1]->kind != ZEND_AST_ARRAY + || !zend_try_ct_eval_array(&array.u.constant, args->child[1])) { + return FAILURE; + } + + if (zend_hash_num_elements(Z_ARRVAL(array.u.constant)) > 0) { + zend_bool ok = 1; + zval *val, tmp; + zend_ulong idx; + HashTable *src = Z_ARRVAL(array.u.constant); + HashTable *dst = emalloc(sizeof(HashTable)); + + zend_hash_init(dst, zend_hash_num_elements(src), NULL, ZVAL_PTR_DTOR, 0); + ZVAL_TRUE(&tmp); + + if (strict) { + ZEND_HASH_FOREACH_VAL(src, val) { + if (Z_TYPE_P(val) == IS_STRING) { + zend_hash_add(dst, Z_STR_P(val), &tmp); + } else if (Z_TYPE_P(val) == IS_LONG) { + zend_hash_index_add(dst, Z_LVAL_P(val), &tmp); + } else { + zend_array_destroy(dst); + ok = 0; + break; + } + } ZEND_HASH_FOREACH_END(); + } else { + ZEND_HASH_FOREACH_VAL(src, val) { + if (Z_TYPE_P(val) != IS_STRING || ZEND_HANDLE_NUMERIC(Z_STR_P(val), idx)) { + zend_array_destroy(dst); + ok = 0; + break; + } + zend_hash_add(dst, Z_STR_P(val), &tmp); + } ZEND_HASH_FOREACH_END(); + } + + zend_array_destroy(src); + if (!ok) { + return FAILURE; + } + Z_ARRVAL(array.u.constant) = dst; + } + array.op_type = IS_CONST; + + zend_compile_expr(&needly, args->child[0]); + + opline = zend_emit_op_tmp(result, ZEND_IN_ARRAY, &needly, &array); + opline->extended_value = strict; + + return SUCCESS; +} +/* }}} */ + int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_list *args, zend_function *fbc, uint32_t type) /* {{{ */ { if (fbc->internal_function.handler == ZEND_FN(display_disabled_function)) { @@ -3693,6 +3765,8 @@ int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_l return zend_compile_func_cufa(result, args, lcname); } else if (zend_string_equals_literal(lcname, "call_user_func")) { return zend_compile_func_cuf(result, args, lcname); + } else if (zend_string_equals_literal(lcname, "in_array")) { + return zend_compile_func_in_array(result, args); } else { return FAILURE; } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index db1c3710c5..66c4933066 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8102,6 +8102,49 @@ ZEND_VM_HANDLER(188, ZEND_SWITCH_STRING, CONST|TMPVAR|CV, CONST, JMP_ADDR) } } +ZEND_VM_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM) +{ + USE_OPLINE + zend_free_op free_op1; + zval *op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); + HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + int result; + + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_exists(ht, Z_STR_P(op1)); + } else if (opline->extended_value) { + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_exists(ht, Z_LVAL_P(op1)); + } else { + result = 0; + } + } else if (Z_TYPE_P(op1) <= IS_FALSE) { + result = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC()); + } else { + zend_string *key; + zval tmp; + + result = 0; + SAVE_OPLINE(); + ZEND_HASH_FOREACH_STR_KEY(ht, key) { + ZVAL_STR(&tmp, key); + compare_function(&tmp, op1, &tmp); + if (Z_LVAL(tmp) == 0) { + result = 1; + break; + } + } ZEND_HASH_FOREACH_END(); + FREE_OP1(); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + FREE_OP1(); + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_ADD, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE)) { USE_OPLINE diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index dd2a612fb8..832add01c4 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6419,6 +6419,49 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_CONST_CONST } } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *op1 = EX_CONSTANT(opline->op1); + HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + int result; + + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_exists(ht, Z_STR_P(op1)); + } else if (opline->extended_value) { + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_exists(ht, Z_LVAL_P(op1)); + } else { + result = 0; + } + } else if (Z_TYPE_P(op1) <= IS_FALSE) { + result = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC()); + } else { + zend_string *key; + zval tmp; + + result = 0; + SAVE_OPLINE(); + ZEND_HASH_FOREACH_STR_KEY(ht, key) { + ZVAL_STR(&tmp, key); + compare_function(&tmp, op1, &tmp); + if (Z_LVAL(tmp) == 0) { + result = 1; + break; + } + } ZEND_HASH_FOREACH_END(); + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -13768,6 +13811,49 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z ZEND_VM_RETURN(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + int result; + + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_exists(ht, Z_STR_P(op1)); + } else if (opline->extended_value) { + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_exists(ht, Z_LVAL_P(op1)); + } else { + result = 0; + } + } else if (Z_TYPE_P(op1) <= IS_FALSE) { + result = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC()); + } else { + zend_string *key; + zval tmp; + + result = 0; + SAVE_OPLINE(); + ZEND_HASH_FOREACH_STR_KEY(ht, key) { + ZVAL_STR(&tmp, key); + compare_function(&tmp, op1, &tmp); + if (Z_LVAL(tmp) == 0) { + result = 1; + break; + } + } ZEND_HASH_FOREACH_END(); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -19857,6 +19943,49 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z ZEND_VM_RETURN(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); + HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + int result; + + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_exists(ht, Z_STR_P(op1)); + } else if (opline->extended_value) { + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_exists(ht, Z_LVAL_P(op1)); + } else { + result = 0; + } + } else if (Z_TYPE_P(op1) <= IS_FALSE) { + result = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC()); + } else { + zend_string *key; + zval tmp; + + result = 0; + SAVE_OPLINE(); + ZEND_HASH_FOREACH_STR_KEY(ht, key) { + ZVAL_STR(&tmp, key); + compare_function(&tmp, op1, &tmp); + if (Z_LVAL(tmp) == 0) { + result = 1; + break; + } + } ZEND_HASH_FOREACH_END(); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -38198,6 +38327,49 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_CV_CONST_HA } } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); + HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + int result; + + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_exists(ht, Z_STR_P(op1)); + } else if (opline->extended_value) { + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_exists(ht, Z_LVAL_P(op1)); + } else { + result = 0; + } + } else if (Z_TYPE_P(op1) <= IS_FALSE) { + result = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC()); + } else { + zend_string *key; + zval tmp; + + result = 0; + SAVE_OPLINE(); + ZEND_HASH_FOREACH_STR_KEY(ht, key) { + ZVAL_STR(&tmp, key); + compare_function(&tmp, op1, &tmp); + if (Z_LVAL(tmp) == 0) { + result = 1; + break; + } + } ZEND_HASH_FOREACH_END(); + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -57770,6 +57942,31 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IN_ARRAY_SPEC_CONST_CONST_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IN_ARRAY_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IN_ARRAY_SPEC_VAR_CONST_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IN_ARRAY_SPEC_CV_CONST_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_LABEL, @@ -59159,6 +59356,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_SWITCH_STRING_SPEC_CONST_CONST): ZEND_SWITCH_STRING_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_IN_ARRAY_SPEC_CONST_CONST): + ZEND_IN_ARRAY_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CONST): ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -59672,6 +59872,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_YIELD_SPEC_TMP_CONST): ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_IN_ARRAY_SPEC_TMP_CONST): + ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_TMP_TMP): ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60059,6 +60262,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_YIELD_SPEC_VAR_CONST): ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_IN_ARRAY_SPEC_VAR_CONST): + ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_VAR_TMP): ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -61316,6 +61522,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_SWITCH_STRING_SPEC_CV_CONST): ZEND_SWITCH_STRING_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_IN_ARRAY_SPEC_CV_CONST): + ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST): ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -66410,6 +66619,31 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_IN_ARRAY_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IN_ARRAY_SPEC_VAR_CONST_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_IN_ARRAY_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER, @@ -67478,7 +67712,7 @@ void zend_init_opcodes_handlers(void) 2257 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2282 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2307 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 4646, + 4671, 2332, 2333, 2334, @@ -67563,11 +67797,12 @@ void zend_init_opcodes_handlers(void) 3531 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3556 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3581 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 4646, + 4671, 3606 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3631 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3656 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 4646 + 3681 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 4671 }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -67762,7 +67997,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3681 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3706 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -67770,7 +68005,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3706 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3731 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -67778,7 +68013,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3731 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3756 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -67789,17 +68024,17 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3756 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3781 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3781 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3806 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3806 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3831 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -67807,7 +68042,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3831 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3856 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -67815,7 +68050,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3856 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3881 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -67823,7 +68058,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3881 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3906 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -67834,7 +68069,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3906 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3931 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -67842,7 +68077,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3981 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4006 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -67853,7 +68088,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4056 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4081 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -67861,7 +68096,7 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4131 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4156 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -67872,12 +68107,12 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4206 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4231 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4281 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4306 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -67885,70 +68120,70 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4356 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4381 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4431 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4456 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_DOUBLE) { - spec = 4596 | SPEC_RULE_OP1; + spec = 4621 | SPEC_RULE_OP1; } else if (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE)))) { - spec = 4601 | SPEC_RULE_OP1; + spec = 4626 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4506 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4531 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 4516 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4541 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4526 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4551 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4536 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4561 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 4546 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4571 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4556 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4581 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4566 | SPEC_RULE_OP1; + spec = 4591 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_LONG) { - spec = 4571 | SPEC_RULE_OP1; + spec = 4596 | SPEC_RULE_OP1; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4576 | SPEC_RULE_OP1; + spec = 4601 | SPEC_RULE_OP1; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4581 | SPEC_RULE_OP1; + spec = 4606 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_LONG) { - spec = 4586 | SPEC_RULE_OP1; + spec = 4611 | SPEC_RULE_OP1; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4591 | SPEC_RULE_OP1; + spec = 4616 | SPEC_RULE_OP1; } break; case ZEND_SEND_VAR_EX: if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 4636 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG; + spec = 4661 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG; } break; case ZEND_FETCH_DIM_R: if (!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) { - spec = 4606 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 4631 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_SEND_VAR: if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 4631 | SPEC_RULE_OP1; + spec = 4656 | SPEC_RULE_OP1; } break; default: diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 315f6e4a8e..eba840096d 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -21,7 +21,7 @@ #include #include -static const char *zend_vm_opcodes_names[189] = { +static const char *zend_vm_opcodes_names[190] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -211,9 +211,10 @@ static const char *zend_vm_opcodes_names[189] = { "ZEND_ISSET_ISEMPTY_THIS", "ZEND_SWITCH_LONG", "ZEND_SWITCH_STRING", + "ZEND_IN_ARRAY", }; -static uint32_t zend_vm_opcodes_flags[189] = { +static uint32_t zend_vm_opcodes_flags[190] = { 0x00000000, 0x00000707, 0x00000707, @@ -403,6 +404,7 @@ static uint32_t zend_vm_opcodes_flags[189] = { 0x00000101, 0x03000307, 0x03000307, + 0x01000303, }; ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) { diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index c0297ad3c5..299a3c2ebc 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -260,7 +260,8 @@ END_EXTERN_C() #define ZEND_ISSET_ISEMPTY_THIS 186 #define ZEND_SWITCH_LONG 187 #define ZEND_SWITCH_STRING 188 +#define ZEND_IN_ARRAY 189 -#define ZEND_VM_LAST_OPCODE 188 +#define ZEND_VM_LAST_OPCODE 189 #endif