From: Dmitry Stogov Date: Thu, 25 May 2017 15:41:28 +0000 (+0300) Subject: Added ZEND_GET_CLASS, ZEMD_GET_CALLED_CLASS, ZEND_GET_TYPE instructions, to implement... X-Git-Tag: php-7.2.0alpha1~57^2~26 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f00d1c72b4dbaf3532569d20efc1da7c408605d6;p=php Added ZEND_GET_CLASS, ZEMD_GET_CALLED_CLASS, ZEND_GET_TYPE instructions, to implement corresponding builtin functions. --- diff --git a/NEWS b/NEWS index 1e3803a6e6..9b2544beb5 100644 --- a/NEWS +++ b/NEWS @@ -3,7 +3,8 @@ PHP NEWS ?? ??? ????, PHP 7.2 - Core: - . Added ZEND_COUNT instruction, to implement corresponding builtin. (Dmitry) + . Added ZEND_COUNT, ZEND_GET_CLASS, ZEMD_GET_CALLED_CLASS, ZEND_GET_TYPE + instructions, to implement corresponding builtin functions. (Dmitry) . "Countable" interface is moved from SPL to Core. (Dmitry) . Added ZEND_IN_ARRAY instruction, implementing optimized in_array() builtin function, through hash lookup in flipped array. (Dmitry) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 0274a288b6..c95d462872 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -202,6 +202,36 @@ ZEND_API char *zend_zval_type_name(const zval *arg) /* {{{ */ } /* }}} */ +ZEND_API zend_string *zend_zval_get_type(const zval *arg) /* {{{ */ +{ + switch (Z_TYPE_P(arg)) { + case IS_NULL: + return ZSTR_KNOWN(ZEND_STR_NULL); + case IS_FALSE: + case IS_TRUE: + return ZSTR_KNOWN(ZEND_STR_BOOLEAN); + case IS_LONG: + return ZSTR_KNOWN(ZEND_STR_INTEGER); + case IS_DOUBLE: + return ZSTR_KNOWN(ZEND_STR_DOUBLE); + case IS_STRING: + return ZSTR_KNOWN(ZEND_STR_STRING); + case IS_ARRAY: + return ZSTR_KNOWN(ZEND_STR_ARRAY); + case IS_OBJECT: + return ZSTR_KNOWN(ZEND_STR_OBJECT); + case IS_RESOURCE: + if (zend_rsrc_list_get_rsrc_type(Z_RES_P(arg))) { + return ZSTR_KNOWN(ZEND_STR_RESOURCE); + } else { + return ZSTR_KNOWN(ZEND_STR_CLOSED_RESOURCE); + } + default: + return NULL; + } +} +/* }}} */ + ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(zend_bool throw_, int num_args, int min_num_args, int max_num_args) /* {{{ */ { zend_function *active_function = EG(current_execute_data)->func; diff --git a/Zend/zend_API.h b/Zend/zend_API.h index b8a6ecfcb7..4a1a0d4617 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -277,6 +277,7 @@ ZEND_API int zend_parse_parameters(int num_args, const char *type_spec, ...); ZEND_API int zend_parse_parameters_ex(int flags, int num_args, const char *type_spec, ...); ZEND_API int zend_parse_parameters_throw(int num_args, const char *type_spec, ...); ZEND_API char *zend_zval_type_name(const zval *arg); +ZEND_API zend_string *zend_zval_get_type(const zval *arg); ZEND_API int zend_parse_method_parameters(int num_args, zval *this_ptr, const char *type_spec, ...); ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this_ptr, const char *type_spec, ...); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2858e6a906..372fddc5f5 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3737,6 +3737,51 @@ int zend_compile_func_count(znode *result, zend_ast_list *args) /* {{{ */ } /* }}} */ +int zend_compile_func_get_class(znode *result, zend_ast_list *args) /* {{{ */ +{ + if (args->children == 0) { + zend_emit_op_tmp(result, ZEND_GET_CLASS, NULL, NULL); + } else { + znode arg_node; + + if (args->children != 1 || args->child[0]->kind == ZEND_AST_UNPACK) { + return FAILURE; + } + + zend_compile_expr(&arg_node, args->child[0]); + zend_emit_op_tmp(result, ZEND_GET_CLASS, &arg_node, NULL); + } + return SUCCESS; +} +/* }}} */ + +int zend_compile_func_get_called_class(znode *result, zend_ast_list *args) /* {{{ */ +{ + znode arg_node; + + if (args->children != 0) { + return FAILURE; + } + + zend_emit_op_tmp(result, ZEND_GET_CALLED_CLASS, &arg_node, NULL); + return SUCCESS; +} +/* }}} */ + +int zend_compile_func_gettype(znode *result, zend_ast_list *args) /* {{{ */ +{ + znode arg_node; + + if (args->children != 1 || args->child[0]->kind == ZEND_AST_UNPACK) { + return FAILURE; + } + + zend_compile_expr(&arg_node, args->child[0]); + zend_emit_op_tmp(result, ZEND_GET_TYPE, &arg_node, NULL); + 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)) { @@ -3799,6 +3844,12 @@ int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_l return zend_compile_func_in_array(result, args); } else if (zend_string_equals_literal(lcname, "count")) { return zend_compile_func_count(result, args); + } else if (zend_string_equals_literal(lcname, "get_class")) { + return zend_compile_func_get_class(result, args); + } else if (zend_string_equals_literal(lcname, "get_called_class")) { + return zend_compile_func_get_called_class(result, args); + } else if (zend_string_equals_literal(lcname, "gettype")) { + return zend_compile_func_gettype(result, args); } else { return FAILURE; } diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 81db801783..7277101efd 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -416,6 +416,13 @@ EMPTY_SWITCH_DEFAULT_CASE() _(ZEND_STR_PATH, "path") \ _(ZEND_STR_QUERY, "query") \ _(ZEND_STR_FRAGMENT, "fragment") \ + _(ZEND_STR_NULL, "NULL") \ + _(ZEND_STR_BOOLEAN, "boolean") \ + _(ZEND_STR_INTEGER, "integer") \ + _(ZEND_STR_DOUBLE, "double") \ + _(ZEND_STR_ARRAY, "array") \ + _(ZEND_STR_RESOURCE, "resource") \ + _(ZEND_STR_CLOSED_RESOURCE, "resource (closed)") \ typedef enum _zend_known_string_id { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 621e5a75d0..9b8d0670bb 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8188,6 +8188,75 @@ ZEND_VM_HANDLER(190, ZEND_COUNT, CONST|TMP|VAR|CV, UNUSED) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +ZEND_VM_HANDLER(191, ZEND_GET_CLASS, UNUSED|CONST|TMP|VAR|CV, UNUSED) +{ + USE_OPLINE + + if (OP1_TYPE == IS_UNUSED) { + if (UNEXPECTED(!EX(func)->common.scope)) { + SAVE_OPLINE(); + zend_error(E_WARNING, "get_class() called without object from outside a class"); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); + ZEND_VM_NEXT_OPCODE(); + } + } else { + zend_free_op free_op1; + zval *op1; + + SAVE_OPLINE(); + op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); + if (Z_TYPE_P(op1) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); + } else { + zend_error(E_WARNING, "get_class() expects parameter 1 to be object, %s given", zend_get_type_by_const(Z_TYPE_P(op1))); + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + +ZEND_VM_HANDLER(192, ZEND_GET_CALLED_CLASS, UNUSED, UNUSED) +{ + USE_OPLINE + + if (Z_TYPE(EX(This)) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE(EX(This))->name); + } else if (Z_CE(EX(This))) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_CE(EX(This))->name); + } else { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (UNEXPECTED(!EX(func)->common.scope)) { + SAVE_OPLINE(); + zend_error(E_WARNING, "get_called_class() called from outside a class"); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_HANDLER(193, ZEND_GET_TYPE, CONST|TMP|VAR|CV, UNUSED) +{ + USE_OPLINE + zend_free_op free_op1; + zval *op1; + zend_string *type; + + SAVE_OPLINE(); + op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); + type = zend_zval_get_type(op1); + if (EXPECTED(type)) { + ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); + } else { + ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); + } + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + 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 b2c701c47b..aa2175e4c9 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -8115,6 +8115,56 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_UNUSED_HANDLE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (IS_CONST == IS_UNUSED) { + if (UNEXPECTED(!EX(func)->common.scope)) { + SAVE_OPLINE(); + zend_error(E_WARNING, "get_class() called without object from outside a class"); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); + ZEND_VM_NEXT_OPCODE(); + } + } else { + + zval *op1; + + SAVE_OPLINE(); + op1 = EX_CONSTANT(opline->op1); + if (Z_TYPE_P(op1) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); + } else { + zend_error(E_WARNING, "get_class() expects parameter 1 to be object, %s given", zend_get_type_by_const(Z_TYPE_P(op1))); + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *op1; + zend_string *type; + + SAVE_OPLINE(); + op1 = EX_CONSTANT(opline->op1); + type = zend_zval_get_type(op1); + if (EXPECTED(type)) { + ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); + } else { + ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -14629,6 +14679,56 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_TMP_UNUSED_HANDLER( ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (IS_TMP_VAR == IS_UNUSED) { + if (UNEXPECTED(!EX(func)->common.scope)) { + SAVE_OPLINE(); + zend_error(E_WARNING, "get_class() called without object from outside a class"); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); + ZEND_VM_NEXT_OPCODE(); + } + } else { + zend_free_op free_op1; + zval *op1; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + if (Z_TYPE_P(op1) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); + } else { + zend_error(E_WARNING, "get_class() expects parameter 1 to be object, %s given", zend_get_type_by_const(Z_TYPE_P(op1))); + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *op1; + zend_string *type; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + type = zend_zval_get_type(op1); + if (EXPECTED(type)) { + ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); + } else { + ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -21751,6 +21851,56 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_VAR_UNUSED_HANDLER( ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (IS_VAR == IS_UNUSED) { + if (UNEXPECTED(!EX(func)->common.scope)) { + SAVE_OPLINE(); + zend_error(E_WARNING, "get_class() called without object from outside a class"); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); + ZEND_VM_NEXT_OPCODE(); + } + } else { + zend_free_op free_op1; + zval *op1; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); + if (Z_TYPE_P(op1) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); + } else { + zend_error(E_WARNING, "get_class() expects parameter 1 to be object, %s given", zend_get_type_by_const(Z_TYPE_P(op1))); + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *op1; + zend_string *type; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); + type = zend_zval_get_type(op1); + if (EXPECTED(type)) { + ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); + } else { + ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -29263,6 +29413,56 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED ZEND_VM_NEXT_OPCODE(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (IS_UNUSED == IS_UNUSED) { + if (UNEXPECTED(!EX(func)->common.scope)) { + SAVE_OPLINE(); + zend_error(E_WARNING, "get_class() called without object from outside a class"); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); + ZEND_VM_NEXT_OPCODE(); + } + } else { + + zval *op1; + + SAVE_OPLINE(); + op1 = NULL; + if (Z_TYPE_P(op1) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); + } else { + zend_error(E_WARNING, "get_class() expects parameter 1 to be object, %s given", zend_get_type_by_const(Z_TYPE_P(op1))); + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (Z_TYPE(EX(This)) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE(EX(This))->name); + } else if (Z_CE(EX(This))) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_CE(EX(This))->name); + } else { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (UNEXPECTED(!EX(func)->common.scope)) { + SAVE_OPLINE(); + zend_error(E_WARNING, "get_called_class() called from outside a class"); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE @@ -40853,6 +41053,56 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(Z ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (IS_CV == IS_UNUSED) { + if (UNEXPECTED(!EX(func)->common.scope)) { + SAVE_OPLINE(); + zend_error(E_WARNING, "get_class() called without object from outside a class"); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); + ZEND_VM_NEXT_OPCODE(); + } + } else { + + zval *op1; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); + if (Z_TYPE_P(op1) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); + } else { + zend_error(E_WARNING, "get_class() expects parameter 1 to be object, %s given", zend_get_type_by_const(Z_TYPE_P(op1))); + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *op1; + zend_string *type; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); + type = zend_zval_get_type(op1); + if (EXPECTED(type)) { + ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); + } else { + ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -58165,6 +58415,81 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_COUNT_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_GET_CLASS_SPEC_CONST_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_GET_CLASS_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_GET_CLASS_SPEC_VAR_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_GET_CLASS_SPEC_CV_UNUSED_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_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_NULL_LABEL, + (void*)&&ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_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_GET_TYPE_SPEC_CONST_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_GET_TYPE_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_GET_TYPE_SPEC_VAR_UNUSED_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_GET_TYPE_SPEC_CV_UNUSED_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, (void*)&&ZEND_NULL_LABEL, @@ -59673,6 +59998,12 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_COUNT_SPEC_CONST_UNUSED): ZEND_COUNT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_GET_CLASS_SPEC_CONST_UNUSED): + ZEND_GET_CLASS_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_GET_TYPE_SPEC_CONST_UNUSED): + ZEND_GET_TYPE_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_ADD_SPEC_CONST_CV): ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60111,6 +60442,12 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_COUNT_SPEC_TMP_UNUSED): ZEND_COUNT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_GET_CLASS_SPEC_TMP_UNUSED): + ZEND_GET_CLASS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_GET_TYPE_SPEC_TMP_UNUSED): + ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_TMP_CV): ZEND_IS_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60582,6 +60919,12 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_COUNT_SPEC_VAR_UNUSED): ZEND_COUNT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_GET_CLASS_SPEC_VAR_UNUSED): + ZEND_GET_CLASS_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_GET_TYPE_SPEC_VAR_UNUSED): + ZEND_GET_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_VAR_CV): ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -61104,6 +61447,12 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED): ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_GET_CLASS_SPEC_UNUSED_UNUSED): + ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED): + ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_UNUSED_CV_OBJ): ZEND_ASSIGN_ADD_SPEC_UNUSED_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -61923,6 +62272,12 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_COUNT_SPEC_CV_UNUSED): ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_GET_CLASS_SPEC_CV_UNUSED): + ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_GET_TYPE_SPEC_CV_UNUSED): + ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_ADD_SPEC_CV_CV): ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -66879,6 +67234,81 @@ void zend_init_opcodes_handlers(void) ZEND_COUNT_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_GET_CLASS_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_GET_CLASS_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_GET_CLASS_SPEC_VAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_GET_CLASS_SPEC_CV_UNUSED_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_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_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_GET_TYPE_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_GET_TYPE_SPEC_VAR_UNUSED_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_GET_TYPE_SPEC_CV_UNUSED_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, ZEND_NULL_HANDLER, @@ -67946,7 +68376,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, - 4696, + 4771, 2332, 2333, 2334, @@ -68031,13 +68461,16 @@ 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, - 4696, + 4771, 3606 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3631 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3656 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3681 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3706 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 4696 + 3731 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 3756 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 3781 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 4771 }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -68232,7 +68665,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 = 3806 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -68240,7 +68673,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 = 3756 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3831 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -68248,7 +68681,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 = 3781 | 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); } @@ -68259,17 +68692,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 = 3806 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3881 | 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 = 3831 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3906 | 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 = 3856 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3931 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -68277,7 +68710,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 = 3956 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -68285,7 +68718,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 = 3981 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -68293,7 +68726,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 = 3931 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 4006 | SPEC_RULE_OP1 | SPEC_RULE_OP2; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -68304,7 +68737,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 = 3956 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4031 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -68312,7 +68745,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 = 4031 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4106 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -68323,7 +68756,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 = 4106 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4181 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -68331,7 +68764,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 = 4181 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4256 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; if (op->op1_type > op->op2_type) { zend_swap_operands(op); } @@ -68342,12 +68775,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 = 4256 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4331 | 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 = 4331 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4406 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -68355,70 +68788,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 = 4406 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4481 | 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 = 4481 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4556 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_DOUBLE) { - spec = 4646 | SPEC_RULE_OP1; + spec = 4721 | 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 = 4651 | SPEC_RULE_OP1; + spec = 4726 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4556 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4631 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 4566 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4641 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4576 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4651 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4586 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4661 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 4596 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4671 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4606 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4681 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4616 | SPEC_RULE_OP1; + spec = 4691 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_LONG) { - spec = 4621 | SPEC_RULE_OP1; + spec = 4696 | SPEC_RULE_OP1; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4626 | SPEC_RULE_OP1; + spec = 4701 | SPEC_RULE_OP1; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4631 | SPEC_RULE_OP1; + spec = 4706 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_LONG) { - spec = 4636 | SPEC_RULE_OP1; + spec = 4711 | SPEC_RULE_OP1; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4641 | SPEC_RULE_OP1; + spec = 4716 | SPEC_RULE_OP1; } break; case ZEND_SEND_VAR_EX: if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 4686 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG; + spec = 4761 | 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 = 4656 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 4731 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_SEND_VAR: if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 4681 | SPEC_RULE_OP1; + spec = 4756 | SPEC_RULE_OP1; } break; default: diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 22349193f9..0d0fc51455 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[191] = { +static const char *zend_vm_opcodes_names[194] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -213,9 +213,12 @@ static const char *zend_vm_opcodes_names[191] = { "ZEND_SWITCH_STRING", "ZEND_IN_ARRAY", "ZEND_COUNT", + "ZEND_GET_CLASS", + "ZEND_GET_CALLED_CLASS", + "ZEND_GET_TYPE", }; -static uint32_t zend_vm_opcodes_flags[191] = { +static uint32_t zend_vm_opcodes_flags[194] = { 0x00000000, 0x00000707, 0x00000707, @@ -407,6 +410,9 @@ static uint32_t zend_vm_opcodes_flags[191] = { 0x03000307, 0x01000303, 0x00000103, + 0x00000103, + 0x00000101, + 0x00000103, }; 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 60a1a26168..ed4bb73b27 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -262,7 +262,10 @@ END_EXTERN_C() #define ZEND_SWITCH_STRING 188 #define ZEND_IN_ARRAY 189 #define ZEND_COUNT 190 +#define ZEND_GET_CLASS 191 +#define ZEND_GET_CALLED_CLASS 192 +#define ZEND_GET_TYPE 193 -#define ZEND_VM_LAST_OPCODE 190 +#define ZEND_VM_LAST_OPCODE 193 #endif diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c index d9fc42bf80..f9992d539a 100644 --- a/ext/opcache/Optimizer/zend_func_info.c +++ b/ext/opcache/Optimizer/zend_func_info.c @@ -589,7 +589,7 @@ static const func_info_t func_infos[] = { F0("doubleval", MAY_BE_NULL | MAY_BE_DOUBLE), FN("strval", MAY_BE_NULL | MAY_BE_STRING), F0("boolval", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), - F1("gettype", MAY_BE_NULL | MAY_BE_STRING), + FN("gettype", MAY_BE_NULL | MAY_BE_STRING), F0("settype", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), FC("is_null", zend_is_type_info), F0("is_resource", MAY_BE_FALSE | MAY_BE_TRUE), // TODO: inline with support for closed resources diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index 01d40bf15d..ee242c4253 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -3163,6 +3163,13 @@ static void zend_update_type_info(const zend_op_array *op_array, case ZEND_COUNT: UPDATE_SSA_TYPE(MAY_BE_LONG, ssa_ops[i].result_def); break; + case ZEND_GET_CLASS: + case ZEND_GET_CALLED_CLASS: + UPDATE_SSA_TYPE(MAY_BE_FALSE|MAY_BE_STRING, ssa_ops[i].result_def); + break; + case ZEND_GET_TYPE: + UPDATE_SSA_TYPE(MAY_BE_STRING, ssa_ops[i].result_def); + break; case ZEND_TYPE_CHECK: case ZEND_DEFINED: UPDATE_SSA_TYPE(MAY_BE_FALSE|MAY_BE_TRUE, ssa_ops[i].result_def); diff --git a/ext/standard/type.c b/ext/standard/type.c index a800050462..1df5a63ecc 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -26,55 +26,17 @@ PHP_FUNCTION(gettype) { zval *arg; + zend_string *type; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_ZVAL_DEREF(arg) ZEND_PARSE_PARAMETERS_END(); - switch (Z_TYPE_P(arg)) { - case IS_NULL: - RETVAL_STRING("NULL"); - break; - - case IS_FALSE: - case IS_TRUE: - RETVAL_STRING("boolean"); - break; - - case IS_LONG: - RETVAL_STRING("integer"); - break; - - case IS_DOUBLE: - RETVAL_STRING("double"); - break; - - case IS_STRING: - RETVAL_STRING("string"); - break; - - case IS_ARRAY: - RETVAL_STRING("array"); - break; - - case IS_OBJECT: - RETVAL_STRING("object"); - break; - - case IS_RESOURCE: - { - const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg)); - - if (type_name) { - RETVAL_STRING("resource"); - } else { - RETVAL_STRING("resource (closed)"); - } - break; - } - - default: - RETVAL_STRING("unknown type"); + type = zend_zval_get_type(arg); + if (EXPECTED(type)) { + RETURN_INTERNED_STR(type); + } else { + RETURN_STRING("unknown type"); } } /* }}} */