From 58a1456064de9b210364d2f78c9e9b6a72bd6c03 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Wed, 11 Aug 2021 11:09:12 -0700 Subject: [PATCH 01/36] Initial commit of user defined operator overloads --- Zend/zend.h | 15 ++++ Zend/zend_API.c | 78 +++++++++++++++++ Zend/zend_compile.c | 19 +++++ Zend/zend_compile.h | 16 ++++ Zend/zend_inheritance.c | 39 +++++++++ Zend/zend_object_handlers.c | 162 +++++++++++++++++++++++++++++++++++- Zend/zend_vm_opcodes.h | 4 +- 7 files changed, 330 insertions(+), 3 deletions(-) diff --git a/Zend/zend.h b/Zend/zend.h index eeacc91eb0a9f..de23de06bd9c3 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -177,6 +177,21 @@ struct _zend_class_entry { zend_function *__serialize; zend_function *__unserialize; + /* operator overloads */ + zend_function *__add; + zend_function *__sub; + zend_function *__mul; + zend_function *__div; + zend_function *__mod; + zend_function *__pow; + zend_function *__equals; + zend_function *__notequals; + zend_function *__lessthan; + zend_function *__lessthanoreq; + zend_function *__greaterthan; + zend_function *__greaterthanoreq; + zend_function *__compareto; + /* allocated only if class implements Iterator or IteratorAggregate interface */ zend_class_iterator_funcs *iterator_funcs_ptr; diff --git a/Zend/zend_API.c b/Zend/zend_API.c index da05581d47c2f..0f25cb12df707 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2484,6 +2484,28 @@ static void zend_check_magic_method_no_return_type( } } +static void zend_check_magic_method_binary_operator_overload( + const zend_class_entry *ce, const zend_function *fptr, int error_type) +{ + zend_check_magic_method_args(2, ce, fptr, error_type); + zend_check_magic_method_non_static(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); + zend_check_magic_method_arg_type(1, ce, fptr, error_type, MAY_BE_BOOL); + zend_check_magic_method_return_type(ce, fptr, error_type, + (MAY_BE_BOOL|MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_ARRAY|MAY_BE_OBJECT)); +} + +static void zend_check_magic_method_comparison_operator_overload( + const zend_class_entry *ce, const zend_function *fptr, int error_type) +{ + zend_check_magic_method_args(1, ce, fptr, error_type); + zend_check_magic_method_non_static(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); + zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_BOOL); +} + ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, zend_string *lcname, int error_type) /* {{{ */ { if (ZSTR_VAL(fptr->common.function_name)[0] != '_' @@ -2576,6 +2598,36 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, zend_check_magic_method_non_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr, error_type); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_VOID); + } else if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_SUB_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_MUL_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_DIV_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_MOD_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) { + zend_check_magic_method_comparison_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_NEQ_FUNC_NAME)) { + zend_check_magic_method_comparison_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_LT_FUNC_NAME)) { + zend_check_magic_method_comparison_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_LTE_FUNC_NAME)) { + zend_check_magic_method_comparison_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_GT_FUNC_NAME)) { + zend_check_magic_method_comparison_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_GTE_FUNC_NAME)) { + zend_check_magic_method_comparison_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { + zend_check_magic_method_args(1, ce, fptr, error_type); + zend_check_magic_method_non_static(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); + zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_LONG); } } /* }}} */ @@ -2615,6 +2667,32 @@ ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, z ce->__serialize = fptr; } else if (zend_string_equals_literal(lcname, "__unserialize")) { ce->__unserialize = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) { + ce->__add = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_SUB_FUNC_NAME)) { + ce->__sub = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_MUL_FUNC_NAME)) { + ce->__mul = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_DIV_FUNC_NAME)) { + ce->__div = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_MOD_FUNC_NAME)) { + ce->__mod = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) { + ce->__pow = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) { + ce->__equals = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_NEQ_FUNC_NAME)) { + ce->__notequals = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_LT_FUNC_NAME)) { + ce->__lessthan = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_LTE_FUNC_NAME)) { + ce->__lessthanoreq = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_GT_FUNC_NAME)) { + ce->__greaterthan = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_GTE_FUNC_NAME)) { + ce->__greaterthanoreq = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { + ce->__compareto = fptr; } } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index af0523264cf58..4a0dfde64b199 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1874,6 +1874,19 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, bool nullify_hand ce->__serialize = NULL; ce->__unserialize = NULL; ce->__debugInfo = NULL; + ce->__add = NULL; + ce->__sub = NULL; + ce->__mul = NULL; + ce->__div = NULL; + ce->__mod = NULL; + ce->__pow = NULL; + ce->__equals = NULL; + ce->__notequals = NULL; + ce->__lessthan = NULL; + ce->__lessthanoreq = NULL; + ce->__greaterthan = NULL; + ce->__greaterthanoreq = NULL; + ce->__compareto = NULL; ce->create_object = NULL; ce->get_iterator = NULL; ce->iterator_funcs_ptr = NULL; @@ -8640,6 +8653,12 @@ void zend_compile_greater(znode *result, zend_ast *ast) /* {{{ */ return; } + if (left_node.op_type == IS_OBJECT || right_node.op_type == IS_OBJECT) { + zend_emit_op_tmp(result, + ast->kind == ZEND_AST_GREATER ? ZEND_IS_LARGER : ZEND_IS_LARGER_OR_EQUAL, + &left_node, &right_node); + } + zend_emit_op_tmp(result, ast->kind == ZEND_AST_GREATER ? ZEND_IS_SMALLER : ZEND_IS_SMALLER_OR_EQUAL, &right_node, &left_node); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index e07b602bfcb54..99950d3d4943e 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1103,6 +1103,22 @@ END_EXTERN_C() #define ZEND_INVOKE_FUNC_NAME "__invoke" #define ZEND_DEBUGINFO_FUNC_NAME "__debuginfo" +/* operator overload functions */ + +#define ZEND_ADD_FUNC_NAME "__add" +#define ZEND_SUB_FUNC_NAME "__sub" +#define ZEND_MUL_FUNC_NAME "__mul" +#define ZEND_DIV_FUNC_NAME "__div" +#define ZEND_MOD_FUNC_NAME "__mod" +#define ZEND_POW_FUNC_NAME "__pow" +#define ZEND_EQ_FUNC_NAME "__equals" +#define ZEND_NEQ_FUNC_NAME "__notequals" +#define ZEND_LT_FUNC_NAME "__lessthan" +#define ZEND_LTE_FUNC_NAME "__lessthanoreq" +#define ZEND_GT_FUNC_NAME "__greaterthan" +#define ZEND_GTE_FUNC_NAME "__greaterthanoreq" +#define ZEND_COMPARE_FUNC_NAME "__compareto" + /* The following constants may be combined in CG(compiler_options) * to change the default compiler behavior */ diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index d2edae17cd364..b645c3fad015d 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -164,6 +164,45 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */ if (EXPECTED(!ce->__debugInfo)) { ce->__debugInfo = parent->__debugInfo; } + if (EXPECTED(!ce->__add)) { + ce->__add = parent->__add; + } + if (EXPECTED(!ce->__sub)) { + ce->__sub = parent->__sub; + } + if (EXPECTED(!ce->__mul)) { + ce->__mul = parent->__mul; + } + if (EXPECTED(!ce->__div)) { + ce->__div = parent->__div; + } + if (EXPECTED(!ce->__mod)) { + ce->__mod = parent->__mod; + } + if (EXPECTED(!ce->__pow)) { + ce->__pow = parent->__pow; + } + if (EXPECTED(!ce->__equals)) { + ce->__equals = parent->__equals; + } + if (EXPECTED(!ce->__notequals)) { + ce->__notequals = parent->__notequals; + } + if (EXPECTED(!ce->__lessthan)) { + ce->__lessthan = parent->__lessthan; + } + if (EXPECTED(!ce->__lessthanoreq)) { + ce->__lessthanoreq = parent->__lessthanoreq; + } + if (EXPECTED(!ce->__greaterthan)) { + ce->__greaterthan = parent->__greaterthan; + } + if (EXPECTED(!ce->__greaterthanoreq)) { + ce->__greaterthanoreq = parent->__greaterthanoreq; + } + if (EXPECTED(!ce->__compareto)) { + ce->__compareto = parent->__compareto; + } if (ce->constructor) { if (parent->constructor && UNEXPECTED(parent->constructor->common.fn_flags & ZEND_ACC_FINAL)) { diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 2bc4a17ce71ad..8ecb578af3814 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -218,6 +218,108 @@ static void zend_std_call_issetter(zend_object *zobj, zend_string *prop_name, zv } /* }}} */ +static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, zval *op2) /* {{{ */ +{ + zend_bool is_retry = 0; + zend_object *zobj; + zend_class_entry *ce; + + if(Z_TYPE_P(op1) == IS_OBJECT) { + zobj = Z_OBJ_P(op1); + ce = Z_OBJCE_P(op1); + } else if(Z_TYPE_P(op2) == IS_OBJECT) { + zobj = Z_OBJ_P(op2); + ce = Z_OBJCE_P(op2); + } + + zend_fcall_info fci; + zend_fcall_info_cache fcic; + + zval params[1]; + params[0] = *op2; + + fci.param_count = 1; + fci.params = params; + fci.size = sizeof(fci); + fci.retval = result; + + do { + fci.object = zobj; + + switch (opcode) { + case ZEND_ADD: + fcic.function_handler = ce->__add; + break; + + case ZEND_SUB: + fcic.function_handler = ce->__sub; + break; + + case ZEND_MUL: + fcic.function_handler = ce->__mul; + break; + + case ZEND_DIV: + fcic.function_handler = ce->__div; + break; + + case ZEND_MOD: + fcic.function_handler = ce->__mod; + break; + + case ZEND_POW: + fcic.function_handler = ce->__pow; + break; + + case ZEND_IS_EQUAL: + fcic.function_handler = ce->__equals; + break; + + case ZEND_IS_NOT_EQUAL: + fcic.function_handler = ce->__notequals; + break; + + case ZEND_IS_SMALLER: + fcic.function_handler = ce->__lessthan; + break; + + case ZEND_IS_SMALLER_OR_EQUAL: + fcic.function_handler = ce->__lessthanoreq; + break; + + case ZEND_IS_LARGER: + fcic.function_handler = ce->__greaterthan; + break; + + case ZEND_IS_LARGER_OR_EQUAL: + fcic.function_handler = ce->__greaterthanoreq; + break; + + default: + return FAILURE; + break; + } + + if (fcic.function_handler == NULL) + { + if(zobj == Z_OBJ_P(op1) && Z_TYPE_P(op2) == IS_OBJECT && !is_retry) { + zobj = Z_OBJ_P(op2); + ce = Z_OBJCE_P(op2); + is_retry = 1; + continue; + } + + return zend_std_compare_objects(op1, op2); + } + + fcic.called_scope = ce; + fcic.object = zobj; + fcic.function_handler->type = ZEND_USER_FUNCTION; + int tmp = zend_call_function(&fci, &fcic); + + return tmp; + } while(1); +} static zend_always_inline bool is_derived_class(zend_class_entry *child_class, zend_class_entry *parent_class) /* {{{ */ { @@ -1571,6 +1673,62 @@ ZEND_API zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */ } /* }}} */ +static int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ +{ + zend_bool is_retry = 0; + zend_object *zobj; + zend_class_entry *ce; + + if(Z_TYPE_P(o1) == IS_OBJECT) { + zobj = Z_OBJ_P(o1); + ce = Z_OBJCE_P(o1); + } else if(Z_TYPE_P(o2) == IS_OBJECT) { + zobj = Z_OBJ_P(o2); + ce = Z_OBJCE_P(o2); + } + + zend_fcall_info fci; + zend_fcall_info_cache fcic; + zval *result; + + zval params[1]; + params[0] = *o2; + + fci.param_count = 1; + fci.params = params; + fci.size = sizeof(fci); + fci.retval = result; + + do { + fci.object = zobj; + fcic.function_handler = ce->__compareto; + + if (fcic.function_handler == NULL) + { + if(zobj == Z_OBJ_P(o1) && Z_TYPE_P(o2) == IS_OBJECT && !is_retry) { + zobj = Z_OBJ_P(o2); + ce = Z_OBJCE_P(o2); + is_retry = 1; + continue; + } + + return zend_std_compare_objects(o1, o2); + } + + fcic.called_scope = ce; + fcic.object = zobj; + fcic.function_handler->type = ZEND_USER_FUNCTION; + int tmp = zend_call_function(&fci, &fcic); + + if (tmp == SUCCESS) { + return result->value.lval; + } else { + return ZEND_UNCOMPARABLE; + } + } while(1); +} +/* }}} */ + ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ { zend_object *zobj1, *zobj2; @@ -1928,7 +2086,7 @@ ZEND_API const zend_object_handlers std_object_handlers = { zend_std_get_debug_info, /* get_debug_info */ zend_std_get_closure, /* get_closure */ zend_std_get_gc, /* get_gc */ - NULL, /* do_operation */ - zend_std_compare_objects, /* compare */ + zend_std_call_op_override, /* do_operation */ + zend_std_user_compare_objects, /* compare */ NULL, /* get_properties_for */ }; diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 83e409a9233c9..8e8abb39ca0ae 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -286,7 +286,9 @@ END_EXTERN_C() #define ZEND_FETCH_GLOBALS 200 #define ZEND_VERIFY_NEVER_TYPE 201 #define ZEND_CALLABLE_CONVERT 202 +#define ZEND_IS_LARGER 203 +#define ZEND_IS_LARGER_OR_EQUAL 204 -#define ZEND_VM_LAST_OPCODE 202 +#define ZEND_VM_LAST_OPCODE 204 #endif From c46492d047aa3cf551166fd7703ffd22f153e935 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Wed, 11 Aug 2021 12:08:49 -0700 Subject: [PATCH 02/36] Added InvalidOperator exception and fixed error handling of operator overloads + whitespace errors --- Zend/zend_compile.h | 16 +++++++------- Zend/zend_exceptions.c | 3 +++ Zend/zend_exceptions.h | 1 + Zend/zend_exceptions_arginfo.h | 14 +++++++++++++ Zend/zend_inheritance.c | 26 +++++++++++------------ Zend/zend_object_handlers.c | 38 +++++++++++++++++++++++++++++----- 6 files changed, 72 insertions(+), 26 deletions(-) diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 99950d3d4943e..d545746eb7d7d 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1109,15 +1109,15 @@ END_EXTERN_C() #define ZEND_SUB_FUNC_NAME "__sub" #define ZEND_MUL_FUNC_NAME "__mul" #define ZEND_DIV_FUNC_NAME "__div" -#define ZEND_MOD_FUNC_NAME "__mod" +#define ZEND_MOD_FUNC_NAME "__mod" #define ZEND_POW_FUNC_NAME "__pow" -#define ZEND_EQ_FUNC_NAME "__equals" -#define ZEND_NEQ_FUNC_NAME "__notequals" -#define ZEND_LT_FUNC_NAME "__lessthan" -#define ZEND_LTE_FUNC_NAME "__lessthanoreq" -#define ZEND_GT_FUNC_NAME "__greaterthan" -#define ZEND_GTE_FUNC_NAME "__greaterthanoreq" -#define ZEND_COMPARE_FUNC_NAME "__compareto" +#define ZEND_EQ_FUNC_NAME "__equals" +#define ZEND_NEQ_FUNC_NAME "__notequals" +#define ZEND_LT_FUNC_NAME "__lessthan" +#define ZEND_LTE_FUNC_NAME "__lessthanoreq" +#define ZEND_GT_FUNC_NAME "__greaterthan" +#define ZEND_GTE_FUNC_NAME "__greaterthanoreq" +#define ZEND_COMPARE_FUNC_NAME "__compareto" /* The following constants may be combined in CG(compiler_options) * to change the default compiler behavior */ diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 2380a24727aec..063713ccc76e4 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -774,6 +774,9 @@ void zend_register_default_exception(void) /* {{{ */ zend_ce_unhandled_match_error = register_class_UnhandledMatchError(zend_ce_error); zend_ce_unhandled_match_error->create_object = zend_default_exception_new; + zend_ce_operator_error = register_class_InvalidOperator(zend_ce_error); + zend_ce_operator_error->create_object = zend_default_exception_new; + INIT_CLASS_ENTRY(zend_ce_unwind_exit, "UnwindExit", NULL); INIT_CLASS_ENTRY(zend_ce_graceful_exit, "GracefulExit", NULL); diff --git a/Zend/zend_exceptions.h b/Zend/zend_exceptions.h index f61b5ecb304e2..7c649124996c3 100644 --- a/Zend/zend_exceptions.h +++ b/Zend/zend_exceptions.h @@ -36,6 +36,7 @@ extern ZEND_API zend_class_entry *zend_ce_value_error; extern ZEND_API zend_class_entry *zend_ce_arithmetic_error; extern ZEND_API zend_class_entry *zend_ce_division_by_zero_error; extern ZEND_API zend_class_entry *zend_ce_unhandled_match_error; +extern ZEND_API zend_class_entry *zend_ce_operator_error; ZEND_API void zend_exception_set_previous(zend_object *exception, zend_object *add_previous); ZEND_API void zend_exception_save(void); diff --git a/Zend/zend_exceptions_arginfo.h b/Zend/zend_exceptions_arginfo.h index c27de25cf70e1..2a5a6845c694e 100644 --- a/Zend/zend_exceptions_arginfo.h +++ b/Zend/zend_exceptions_arginfo.h @@ -187,6 +187,10 @@ static const zend_function_entry class_UnhandledMatchError_methods[] = { ZEND_FE_END }; +static const zend_function_entry class_InvalidOperator_methods[] = { + ZEND_FE_END +}; + static zend_class_entry *register_class_Throwable(zend_class_entry *class_entry_Stringable) { zend_class_entry ce, *class_entry; @@ -395,3 +399,13 @@ static zend_class_entry *register_class_UnhandledMatchError(zend_class_entry *cl return class_entry; } + +static zend_class_entry *register_class_InvalidOperator(zend_class_entry *class_entry_Error) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "InvalidOperator", class_InvalidOperator_methods); + class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + + return class_entry; +} diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index b645c3fad015d..41daad57b28d4 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -165,43 +165,43 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */ ce->__debugInfo = parent->__debugInfo; } if (EXPECTED(!ce->__add)) { - ce->__add = parent->__add; + ce->__add = parent->__add; } if (EXPECTED(!ce->__sub)) { - ce->__sub = parent->__sub; + ce->__sub = parent->__sub; } if (EXPECTED(!ce->__mul)) { - ce->__mul = parent->__mul; + ce->__mul = parent->__mul; } if (EXPECTED(!ce->__div)) { - ce->__div = parent->__div; + ce->__div = parent->__div; } if (EXPECTED(!ce->__mod)) { - ce->__mod = parent->__mod; + ce->__mod = parent->__mod; } if (EXPECTED(!ce->__pow)) { - ce->__pow = parent->__pow; + ce->__pow = parent->__pow; } if (EXPECTED(!ce->__equals)) { - ce->__equals = parent->__equals; + ce->__equals = parent->__equals; } if (EXPECTED(!ce->__notequals)) { - ce->__notequals = parent->__notequals; + ce->__notequals = parent->__notequals; } if (EXPECTED(!ce->__lessthan)) { - ce->__lessthan = parent->__lessthan; + ce->__lessthan = parent->__lessthan; } if (EXPECTED(!ce->__lessthanoreq)) { - ce->__lessthanoreq = parent->__lessthanoreq; + ce->__lessthanoreq = parent->__lessthanoreq; } if (EXPECTED(!ce->__greaterthan)) { - ce->__greaterthan = parent->__greaterthan; + ce->__greaterthan = parent->__greaterthan; } if (EXPECTED(!ce->__greaterthanoreq)) { - ce->__greaterthanoreq = parent->__greaterthanoreq; + ce->__greaterthanoreq = parent->__greaterthanoreq; } if (EXPECTED(!ce->__compareto)) { - ce->__compareto = parent->__compareto; + ce->__compareto = parent->__compareto; } if (ce->constructor) { diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 8ecb578af3814..25457b5055322 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -223,6 +223,7 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, zend_bool is_retry = 0; zend_object *zobj; zend_class_entry *ce; + char *operator; if(Z_TYPE_P(op1) == IS_OBJECT) { zobj = Z_OBJ_P(op1); @@ -230,74 +231,97 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, } else if(Z_TYPE_P(op2) == IS_OBJECT) { zobj = Z_OBJ_P(op2); ce = Z_OBJCE_P(op2); + is_retry = 1; } zend_fcall_info fci; zend_fcall_info_cache fcic; - zval params[1]; - params[0] = *op2; + zval params[2]; + zval *left; fci.param_count = 1; - fci.params = params; fci.size = sizeof(fci); fci.retval = result; do { fci.object = zobj; + Z_TYPE_INFO_P(left) = is_retry ? IS_FALSE : IS_TRUE; + + if (zobj == Z_OBJ_P(op1)) { + params[0] = *op2; + params[1] = *left; + } else { + params[0] = *op1; + params[1] = *left; + } + + fci.params = params; + switch (opcode) { case ZEND_ADD: fcic.function_handler = ce->__add; + operator = "+"; break; case ZEND_SUB: fcic.function_handler = ce->__sub; + operator = "-"; break; case ZEND_MUL: fcic.function_handler = ce->__mul; + operator = "*"; break; case ZEND_DIV: fcic.function_handler = ce->__div; + operator = "/"; break; case ZEND_MOD: fcic.function_handler = ce->__mod; + operator = "%"; break; case ZEND_POW: fcic.function_handler = ce->__pow; + operator = "**"; break; case ZEND_IS_EQUAL: fcic.function_handler = ce->__equals; + operator = "=="; break; case ZEND_IS_NOT_EQUAL: fcic.function_handler = ce->__notequals; + operator = "!="; break; case ZEND_IS_SMALLER: fcic.function_handler = ce->__lessthan; + operator = "<"; break; case ZEND_IS_SMALLER_OR_EQUAL: fcic.function_handler = ce->__lessthanoreq; + operator = "<="; break; case ZEND_IS_LARGER: fcic.function_handler = ce->__greaterthan; + operator = ">"; break; case ZEND_IS_LARGER_OR_EQUAL: fcic.function_handler = ce->__greaterthanoreq; + operator = ">="; break; default: return FAILURE; - break; } if (fcic.function_handler == NULL) @@ -309,7 +333,11 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, continue; } - return zend_std_compare_objects(op1, op2); + if (ce->type != ZEND_INTERNAL_CLASS) { + zend_throw_exception_ex(zend_ce_operator_error, 0, "Operator '%s' unsupported by class %s", operator, ZSTR_VAL(ce->name)); + } + + return FAILURE; } fcic.called_scope = ce; From 68110807823ccac5733c641867a1f7b91def98e8 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Fri, 13 Aug 2021 15:08:59 -0700 Subject: [PATCH 03/36] Started on ZEND_IS_LARGER work --- Zend/zend_ast.c | 2 ++ Zend/zend_object_handlers.c | 24 ++++++++++++++++++++---- Zend/zend_opcode.c | 4 ++++ Zend/zend_operators.c | 14 ++++++++++++++ Zend/zend_operators.h | 2 ++ 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 59f8c968b18b1..d622e4068157f 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2009,6 +2009,8 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_IS_NOT_EQUAL: BINARY_OP(" != ", 170, 171, 171); case ZEND_IS_SMALLER: BINARY_OP(" < ", 180, 181, 181); case ZEND_IS_SMALLER_OR_EQUAL: BINARY_OP(" <= ", 180, 181, 181); + case ZEND_IS_LARGER: BINARY_OP(" > ", 180, 181, 181); + case ZEND_IS_LARGER_OR_EQUAL: BINARY_OP(" >= ", 180, 181, 181); case ZEND_POW: BINARY_OP(" ** ", 250, 251, 250); case ZEND_BOOL_XOR: BINARY_OP(" xor ", 40, 40, 41); case ZEND_SPACESHIP: BINARY_OP(" <=> ", 180, 181, 181); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 25457b5055322..4a8e79b320715 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -301,22 +301,38 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, break; case ZEND_IS_SMALLER: - fcic.function_handler = ce->__lessthan; + if (zobj == Z_OBJ_P(op1)) { + fcic.function_handler = ce->__lessthan; + } else { + fcic.function_handler = ce->__greaterthan; + } operator = "<"; break; case ZEND_IS_SMALLER_OR_EQUAL: - fcic.function_handler = ce->__lessthanoreq; + if (zobj == Z_OBJ_P(op1)) { + fcic.function_handler = ce->__lessthanoreq; + } else { + fcic.function_handler = ce->__greaterthanoreq; + } operator = "<="; break; case ZEND_IS_LARGER: - fcic.function_handler = ce->__greaterthan; + if (zobj == Z_OBJ_P(op1)) { + fcic.function_handler = ce->__greaterthan; + } else { + fcic.function_handler = ce->__lessthan; + } operator = ">"; break; case ZEND_IS_LARGER_OR_EQUAL: - fcic.function_handler = ce->__greaterthanoreq; + if (zobj == Z_OBJ_P(op1)) { + fcic.function_handler = ce->__greaterthanoreq; + } else { + fcic.function_handler = ce->__lessthanoreq; + } operator = ">="; break; diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 0ad5d1c57199d..1e5d5df90f1c0 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -1189,6 +1189,10 @@ ZEND_API binary_op_type get_binary_op(int opcode) return (binary_op_type) is_smaller_function; case ZEND_IS_SMALLER_OR_EQUAL: return (binary_op_type) is_smaller_or_equal_function; + case ZEND_IS_LARGER: + return (binary_op_type) is_larger_function; + case ZEND_IS_LARGER_OR_EQUAL: + return (binary_op_type) is_larger_or_equal_function; case ZEND_SPACESHIP: return (binary_op_type) compare_function; case ZEND_BW_OR: diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index f1846030b94bf..d82bfc75429bc 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2299,6 +2299,20 @@ ZEND_API zend_result ZEND_FASTCALL is_smaller_or_equal_function(zval *result, zv } /* }}} */ +ZEND_API zend_result ZEND_FASTCALL is_larger_function(zval *result, zval *op1, zval *op2) /* {{{ */ +{ + ZVAL_BOOL(result, (zend_compare(op1, op2) < 0)); + return SUCCESS; +} +/* }}} */ + +ZEND_API zend_result ZEND_FASTCALL is_larger_or_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */ +{ + ZVAL_BOOL(result, (zend_compare(op1, op2) <= 0)); + return SUCCESS; +} +/* }}} */ + ZEND_API bool ZEND_FASTCALL zend_class_implements_interface(const zend_class_entry *class_ce, const zend_class_entry *interface_ce) /* {{{ */ { uint32_t i; diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index bef2b374e1ba6..27260b8f9b788 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -62,6 +62,8 @@ ZEND_API zend_result ZEND_FASTCALL is_not_identical_function(zval *result, zval ZEND_API zend_result ZEND_FASTCALL is_not_equal_function(zval *result, zval *op1, zval *op2); ZEND_API zend_result ZEND_FASTCALL is_smaller_function(zval *result, zval *op1, zval *op2); ZEND_API zend_result ZEND_FASTCALL is_smaller_or_equal_function(zval *result, zval *op1, zval *op2); +ZEND_API zend_result ZEND_FASTCALL is_larger_function(zval *result, zval *op1, zval *op2); +ZEND_API zend_result ZEND_FASTCALL is_larger_or_equal_function(zval *result, zval *op1, zval *op2); ZEND_API bool ZEND_FASTCALL zend_class_implements_interface(const zend_class_entry *class_ce, const zend_class_entry *interface_ce); ZEND_API bool ZEND_FASTCALL instanceof_function_slow(const zend_class_entry *instance_ce, const zend_class_entry *ce); From 4a84a91008b7648fc28b9866661e1c3511de402c Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Wed, 18 Aug 2021 12:27:09 -0700 Subject: [PATCH 04/36] Further implementation of op overloads --- .../operator_overloads/add_operator.phpt | 31 ++++++++++ .../operator_overloads/div_operator.phpt | 36 ++++++++++++ .../operator_overloads/equals_operator.phpt | 43 ++++++++++++++ .../operator_overloads/mod_operator.phpt | 36 ++++++++++++ .../operator_overloads/mul_operator.phpt | 31 ++++++++++ .../operator_omitted_type.phpt | 19 +++++++ .../operator_unimplemented.phpt | 56 +++++++++++++++++++ .../operator_overloads/pow_operator.phpt | 36 ++++++++++++ .../operator_overloads/sub_operator.phpt | 36 ++++++++++++ Zend/zend_API.c | 14 ++++- Zend/zend_compile.c | 2 + Zend/zend_exceptions.c | 1 + Zend/zend_object_handlers.c | 45 ++++++++++++--- Zend/zend_operators.c | 20 +++++++ Zend/zend_operators.h | 1 + Zend/zend_vm_execute.h | 12 +++- 16 files changed, 406 insertions(+), 13 deletions(-) create mode 100644 Zend/tests/operator_overloads/add_operator.phpt create mode 100644 Zend/tests/operator_overloads/div_operator.phpt create mode 100644 Zend/tests/operator_overloads/equals_operator.phpt create mode 100644 Zend/tests/operator_overloads/mod_operator.phpt create mode 100644 Zend/tests/operator_overloads/mul_operator.phpt create mode 100644 Zend/tests/operator_overloads/operator_omitted_type.phpt create mode 100644 Zend/tests/operator_overloads/operator_unimplemented.phpt create mode 100644 Zend/tests/operator_overloads/pow_operator.phpt create mode 100644 Zend/tests/operator_overloads/sub_operator.phpt diff --git a/Zend/tests/operator_overloads/add_operator.phpt b/Zend/tests/operator_overloads/add_operator.phpt new file mode 100644 index 0000000000000..deff6df64ee4f --- /dev/null +++ b/Zend/tests/operator_overloads/add_operator.phpt @@ -0,0 +1,31 @@ +--TEST-- +operator overload: add operator with scalars +--FILE-- +value = $this->value + $other; + + return $return; + } +} + +$obj = new A(); +$obj->value = 3; + +$num1 = 2 + $obj; + +var_dump($num1->value); + +$num2 = $obj + 3; + +var_dump($num2->value); +?> +--EXPECT-- +int(5) +int(6) diff --git a/Zend/tests/operator_overloads/div_operator.phpt b/Zend/tests/operator_overloads/div_operator.phpt new file mode 100644 index 0000000000000..f15fb3e3b5d8b --- /dev/null +++ b/Zend/tests/operator_overloads/div_operator.phpt @@ -0,0 +1,36 @@ +--TEST-- +operator overload: div operator with scalars +--FILE-- +value = $this->value / $other; + } else { + $return->value = $other / $this->value; + } + + return $return; + } +} + +$obj = new A(); +$obj->value = 6; + +$num1 = 12 / $obj; + +var_dump($num1->value); + +$num2 = $obj / 2; + +var_dump($num2->value); +?> +--EXPECT-- +int(2) +int(3) diff --git a/Zend/tests/operator_overloads/equals_operator.phpt b/Zend/tests/operator_overloads/equals_operator.phpt new file mode 100644 index 0000000000000..a7685ce90ee30 --- /dev/null +++ b/Zend/tests/operator_overloads/equals_operator.phpt @@ -0,0 +1,43 @@ +--TEST-- +operator overload: div operator with scalars +--FILE-- +value == $other); + } +} + +$obj = new A(); +$obj->value = 6; + +$bool1 = 12 == $obj; + +var_dump($bool1); + +$bool2 = $obj == 2; + +var_dump($bool2); + +$bool3 = $obj == 6; + +var_dump($bool3); + +$bool4 = $obj == 6.0; + +var_dump($bool4); + +$bool5 = $obj != 6.0; + +var_dump($bool5); +?> +--EXPECT-- +bool(false) +bool(false) +bool(true) +bool(true) +bool(false) diff --git a/Zend/tests/operator_overloads/mod_operator.phpt b/Zend/tests/operator_overloads/mod_operator.phpt new file mode 100644 index 0000000000000..41414c090ca21 --- /dev/null +++ b/Zend/tests/operator_overloads/mod_operator.phpt @@ -0,0 +1,36 @@ +--TEST-- +operator overload: mod operator with scalars +--FILE-- +value = $this->value % $other; + } else { + $return->value = $other % $this->value; + } + + return $return; + } +} + +$obj = new A(); +$obj->value = 2; + +$num1 = 3 % $obj; + +var_dump($num1->value); + +$num2 = $obj % 4; + +var_dump($num2->value); +?> +--EXPECT-- +int(1) +int(2) diff --git a/Zend/tests/operator_overloads/mul_operator.phpt b/Zend/tests/operator_overloads/mul_operator.phpt new file mode 100644 index 0000000000000..4eb779a377d9e --- /dev/null +++ b/Zend/tests/operator_overloads/mul_operator.phpt @@ -0,0 +1,31 @@ +--TEST-- +operator overload: mul operator with scalars +--FILE-- +value = $this->value * $other; + + return $return; + } +} + +$obj = new A(); +$obj->value = 3; + +$num1 = 2 * $obj; + +var_dump($num1->value); + +$num2 = $obj * 3; + +var_dump($num2->value); +?> +--EXPECT-- +int(6) +int(9) diff --git a/Zend/tests/operator_overloads/operator_omitted_type.phpt b/Zend/tests/operator_overloads/operator_omitted_type.phpt new file mode 100644 index 0000000000000..30d74baf32ad1 --- /dev/null +++ b/Zend/tests/operator_overloads/operator_omitted_type.phpt @@ -0,0 +1,19 @@ +--TEST-- +operator overload: no explicit type +--FILE-- +value = $this->value + $other; + + return $return; + } +} +?> +--EXPECTF-- +Fatal error: A::__add(): Parameter #1 ($other) must explicitly define a type in %s on line %d diff --git a/Zend/tests/operator_overloads/operator_unimplemented.phpt b/Zend/tests/operator_overloads/operator_unimplemented.phpt new file mode 100644 index 0000000000000..59f1928d2b1d1 --- /dev/null +++ b/Zend/tests/operator_overloads/operator_unimplemented.phpt @@ -0,0 +1,56 @@ +--TEST-- +operator overload: unimplemented +--FILE-- +value = $this->value + $other; + } else { + $return->value = $this->value + $other->value; + } + + return $return; + } +} + +$obj1 = new A(); +$obj1->value = 3; +$obj2 = new B(); +$obj2->value = 2; + +try { + $num1 = $obj1 + 2; +} catch (InvalidOperator) { + echo "OK!".PHP_EOL; +} + +try { + $num2 = 2 + $obj1; +} catch (InvalidOperator) { + echo "STILL OK!".PHP_EOL; +} + +$num3 = $obj1 + $obj2; + +var_dump($num3->value); + +$num4 = $obj2 + $obj1; + +var_dump($num4->value); + +?> +--EXPECT-- +OK! +STILL OK! +int(5) +int(5) diff --git a/Zend/tests/operator_overloads/pow_operator.phpt b/Zend/tests/operator_overloads/pow_operator.phpt new file mode 100644 index 0000000000000..4a7914b2a8be9 --- /dev/null +++ b/Zend/tests/operator_overloads/pow_operator.phpt @@ -0,0 +1,36 @@ +--TEST-- +operator overload: pow operator with scalars +--FILE-- +value = $this->value ** $other; + } else { + $return->value = $other ** $this->value; + } + + return $return; + } +} + +$obj = new A(); +$obj->value = 2; + +$num1 = 5 ** $obj; + +var_dump($num1->value); + +$num2 = $obj ** 3; + +var_dump($num2->value); +?> +--EXPECT-- +int(25) +int(8) diff --git a/Zend/tests/operator_overloads/sub_operator.phpt b/Zend/tests/operator_overloads/sub_operator.phpt new file mode 100644 index 0000000000000..88910f249c4c5 --- /dev/null +++ b/Zend/tests/operator_overloads/sub_operator.phpt @@ -0,0 +1,36 @@ +--TEST-- +operator overload: sub operator with scalars +--FILE-- +value = $this->value - $other; + } else { + $return->value = $other - $this->value; + } + + return $return; + } +} + +$obj = new A(); +$obj->value = 3; + +$num1 = 2 - $obj; + +var_dump($num1->value); + +$num2 = $obj - 3; + +var_dump($num2->value); +?> +--EXPECT-- +int(-1) +int(0) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 0f25cb12df707..7bed3ced62fc1 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2426,6 +2426,15 @@ static void zend_check_magic_method_arg_type(uint32_t arg_num, const zend_class_ } } +static void zend_check_magic_method_explicit_type(uint32_t arg_num, const zend_class_entry *ce, const zend_function *fptr, int error_type) +{ + if (!ZEND_TYPE_IS_SET(fptr->common.arg_info[arg_num].type)) { + zend_error(error_type, "%s::%s(): Parameter #%d ($%s) must explicitly define a type", + ZSTR_VAL(ce->name), ZSTR_VAL(fptr->common.function_name), + arg_num + 1, ZSTR_VAL(fptr->common.arg_info[arg_num].name)); + } +} + static void zend_check_magic_method_return_type(const zend_class_entry *ce, const zend_function *fptr, int error_type, int return_type) { if (!(fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) { @@ -2490,10 +2499,9 @@ static void zend_check_magic_method_binary_operator_overload( zend_check_magic_method_args(2, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_explicit_type(0, ce, fptr, error_type); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); zend_check_magic_method_arg_type(1, ce, fptr, error_type, MAY_BE_BOOL); - zend_check_magic_method_return_type(ce, fptr, error_type, - (MAY_BE_BOOL|MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_ARRAY|MAY_BE_OBJECT)); } static void zend_check_magic_method_comparison_operator_overload( @@ -2502,6 +2510,7 @@ static void zend_check_magic_method_comparison_operator_overload( zend_check_magic_method_args(1, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_explicit_type(0, ce, fptr, error_type); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_BOOL); } @@ -2626,6 +2635,7 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, zend_check_magic_method_args(1, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_explicit_type(0, ce, fptr, error_type); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_LONG); } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 4a0dfde64b199..f8996258b4c67 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2161,6 +2161,8 @@ ZEND_API bool zend_is_smart_branch(const zend_op *opline) /* {{{ */ case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_CASE: case ZEND_CASE_STRICT: case ZEND_ISSET_ISEMPTY_CV: diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 063713ccc76e4..f1532d2e08a75 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -42,6 +42,7 @@ ZEND_API zend_class_entry *zend_ce_value_error; ZEND_API zend_class_entry *zend_ce_arithmetic_error; ZEND_API zend_class_entry *zend_ce_division_by_zero_error; ZEND_API zend_class_entry *zend_ce_unhandled_match_error; +ZEND_API zend_class_entry *zend_ce_operator_error; /* Internal pseudo-exception that is not exposed to userland. Throwing this exception *does not* execute finally blocks. */ static zend_class_entry zend_ce_unwind_exit; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 4a8e79b320715..cc832121fa6c1 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -234,27 +234,30 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, is_retry = 1; } + zend_class_entry *orig_fake_scope = EG(fake_scope); + EG(fake_scope) = NULL; + zend_fcall_info fci; zend_fcall_info_cache fcic; zval params[2]; - zval *left; + zval left; - fci.param_count = 1; + fci.param_count = 2; fci.size = sizeof(fci); fci.retval = result; do { fci.object = zobj; - Z_TYPE_INFO_P(left) = is_retry ? IS_FALSE : IS_TRUE; + Z_TYPE_INFO(left) = is_retry ? IS_FALSE : IS_TRUE; if (zobj == Z_OBJ_P(op1)) { - params[0] = *op2; - params[1] = *left; + ZVAL_COPY_VALUE(¶ms[0], op2); + ZVAL_COPY_VALUE(¶ms[1], &left); } else { - params[0] = *op1; - params[1] = *left; + ZVAL_COPY_VALUE(¶ms[0], op1); + ZVAL_COPY_VALUE(¶ms[1], &left); } fci.params = params; @@ -296,7 +299,7 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, break; case ZEND_IS_NOT_EQUAL: - fcic.function_handler = ce->__notequals; + fcic.function_handler = ce->__equals; operator = "!="; break; @@ -359,8 +362,32 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, fcic.called_scope = ce; fcic.object = zobj; fcic.function_handler->type = ZEND_USER_FUNCTION; + fci.named_params = NULL; int tmp = zend_call_function(&fci, &fcic); + if (tmp == SUCCESS) { + switch (opcode) { + case ZEND_IS_NOT_EQUAL: + /* reverse __equals for not equals */ + Z_TYPE_INFO_P(result) = Z_TYPE_INFO_P(result) == IS_TRUE ? IS_FALSE : IS_TRUE; + break; + + case ZEND_IS_SMALLER: + case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: + if (is_retry) { + Z_LVAL_P(result) = Z_LVAL_P(result) * -1; + } + break; + + default: + break; + } + } + + EG(fake_scope) = orig_fake_scope; + return tmp; } while(1); } @@ -1733,7 +1760,7 @@ static int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ zend_fcall_info fci; zend_fcall_info_cache fcic; - zval *result; + zval *result = (result); zval params[1]; params[0] = *o2; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index d82bfc75429bc..1b15be57572cf 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2087,6 +2087,26 @@ static int compare_double_to_string(double dval, zend_string *str) /* {{{ */ } /* }}} */ +ZEND_API int ZEND_FASTCALL zend_equals_object(zval *op1, zval *op2) /* {{{ */ +{ + zval ret; + int retVal; + if (Z_TYPE_P(op1) == IS_OBJECT && + Z_TYPE_P(op2) == IS_OBJECT && + Z_OBJ_P(op1) == Z_OBJ_P(op2)) { + return 0; + } else if (Z_TYPE_P(op1) == IS_OBJECT) { + Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_IS_EQUAL, &ret, op1, op2); + retVal = (Z_TYPE_INFO(ret) == IS_TRUE ? 0 : 1); + return retVal; + } else { + Z_OBJ_HANDLER_P(op2, do_operation)(ZEND_IS_EQUAL, &ret, op1, op2); + retVal = (Z_TYPE_INFO(ret) == IS_TRUE ? 0 : 1); + return retVal; + } +} +/* }}} */ + ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */ { int converted = 0; diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 27260b8f9b788..5b6e2361cadaf 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -425,6 +425,7 @@ static zend_always_inline bool i_zend_is_true(zval *op) // TODO: Use a different value to allow an actual distinction here. #define ZEND_UNCOMPARABLE 1 +ZEND_API int ZEND_FASTCALL zend_equals_object(zval *op1, zval *op2); ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2); ZEND_API zend_result ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index a18ee134c81ed..bfe2cf7bf415c 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -580,7 +580,11 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_equal_hel if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) { op_2 = ZVAL_UNDEFINED_OP2(); } - ret = zend_compare(op_1, op_2); + if (Z_TYPE_P(op_1) == IS_OBJECT || Z_TYPE_P(op_2) == IS_OBJECT) { + ret = zend_equals_object(op_1, op_2); + } else { + ret = zend_compare(op_1, op_2); + } if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_nogc(op_1); } @@ -602,7 +606,11 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_not_equal if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) { op_2 = ZVAL_UNDEFINED_OP2(); } - ret = zend_compare(op_1, op_2); + if (Z_TYPE_P(op_1) == IS_OBJECT || Z_TYPE_P(op_2) == IS_OBJECT) { + ret = zend_equals_object(op_1, op_2); + } else { + ret = zend_compare(op_1, op_2); + } if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_nogc(op_1); } From 6be3d1a6b4b6e92c19db7a956cb46e5cad7af59c Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Thu, 19 Aug 2021 01:06:27 -0700 Subject: [PATCH 05/36] Finished implementation of compare and updated several tests; added special cases --- Zend/tests/bug63882.phpt | 2 +- Zend/tests/class_alias_001.phpt | 10 ++- Zend/tests/clone_002.phpt | 22 +++++-- Zend/tests/objects_001.phpt | 19 +++--- Zend/zend.h | 5 -- Zend/zend_API.c | 20 ------ Zend/zend_ast.c | 2 - Zend/zend_compile.c | 13 ---- Zend/zend_compile.h | 5 -- Zend/zend_inheritance.c | 15 ----- Zend/zend_object_handlers.c | 88 ++++++++------------------ Zend/zend_opcode.c | 4 -- Zend/zend_operators.c | 18 ++++-- Zend/zend_operators.h | 2 +- Zend/zend_vm_execute.h | 4 +- Zend/zend_vm_opcodes.h | 4 +- tests/lang/compare_objects_basic1.phpt | 62 ++++++++++++------ 17 files changed, 122 insertions(+), 173 deletions(-) diff --git a/Zend/tests/bug63882.phpt b/Zend/tests/bug63882.phpt index 0cc1babd49bdf..16ec73799220c 100644 --- a/Zend/tests/bug63882.phpt +++ b/Zend/tests/bug63882.phpt @@ -9,7 +9,7 @@ $testobj2 = new Test; $testobj1->x = $testobj1; $testobj2->x = $testobj2; -var_dump($testobj1 == $testobj2); +var_dump($testobj1 <= $testobj2); ?> --EXPECTF-- Fatal error: Nesting level too deep - recursive dependency? in %sbug63882.php on line 9 diff --git a/Zend/tests/class_alias_001.phpt b/Zend/tests/class_alias_001.phpt index 371f08f80ba16..05cdf43097329 100644 --- a/Zend/tests/class_alias_001.phpt +++ b/Zend/tests/class_alias_001.phpt @@ -10,7 +10,13 @@ class_alias('foo', 'bar'); $a = new foo; $b = new bar; -var_dump($a == $b, $a === $b); +try { + $a == $b; +} catch (InvalidOperator) { + echo "InvalidOperator thrown".PHP_EOL; +} + +var_dump($a === $b); var_dump($a instanceof $b); var_dump($a instanceof foo); @@ -21,7 +27,7 @@ var_dump($b instanceof bar); ?> --EXPECT-- -bool(true) +InvalidOperator thrown bool(false) bool(true) bool(true) diff --git a/Zend/tests/clone_002.phpt b/Zend/tests/clone_002.phpt index 5d9c9aa8e7fad..aba1796fd74ff 100644 --- a/Zend/tests/clone_002.phpt +++ b/Zend/tests/clone_002.phpt @@ -13,13 +13,27 @@ var_dump($a == $b, $b == $c); class foo { } $d = clone $a = $b = new foo; -var_dump($a == $d, $b == $d, $c == $a); +try { + var_dump($a == $d); +} catch (InvalidOperator) { + echo "InvalidOperator thrown".PHP_EOL; +} +try { + var_dump($b == $d); +} catch (InvalidOperator) { + echo "InvalidOperator thrown".PHP_EOL; +} +try { + var_dump($c == $a); +} catch (InvalidOperator) { + echo "InvalidOperator thrown".PHP_EOL; +} ?> --EXPECT-- bool(true) bool(true) bool(true) -bool(true) -bool(true) -bool(false) +InvalidOperator thrown +InvalidOperator thrown +InvalidOperator thrown diff --git a/Zend/tests/objects_001.phpt b/Zend/tests/objects_001.phpt index 42e0b54d31a7c..d2cfca3e01439 100644 --- a/Zend/tests/objects_001.phpt +++ b/Zend/tests/objects_001.phpt @@ -3,10 +3,7 @@ comparing objects to other types --FILE-- __pow = fptr; } else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) { ce->__equals = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_NEQ_FUNC_NAME)) { - ce->__notequals = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_LT_FUNC_NAME)) { - ce->__lessthan = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_LTE_FUNC_NAME)) { - ce->__lessthanoreq = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_GT_FUNC_NAME)) { - ce->__greaterthan = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_GTE_FUNC_NAME)) { - ce->__greaterthanoreq = fptr; } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { ce->__compareto = fptr; } diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index d622e4068157f..59f8c968b18b1 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2009,8 +2009,6 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_IS_NOT_EQUAL: BINARY_OP(" != ", 170, 171, 171); case ZEND_IS_SMALLER: BINARY_OP(" < ", 180, 181, 181); case ZEND_IS_SMALLER_OR_EQUAL: BINARY_OP(" <= ", 180, 181, 181); - case ZEND_IS_LARGER: BINARY_OP(" > ", 180, 181, 181); - case ZEND_IS_LARGER_OR_EQUAL: BINARY_OP(" >= ", 180, 181, 181); case ZEND_POW: BINARY_OP(" ** ", 250, 251, 250); case ZEND_BOOL_XOR: BINARY_OP(" xor ", 40, 40, 41); case ZEND_SPACESHIP: BINARY_OP(" <=> ", 180, 181, 181); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index f8996258b4c67..6d480f3c5a534 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1881,11 +1881,6 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, bool nullify_hand ce->__mod = NULL; ce->__pow = NULL; ce->__equals = NULL; - ce->__notequals = NULL; - ce->__lessthan = NULL; - ce->__lessthanoreq = NULL; - ce->__greaterthan = NULL; - ce->__greaterthanoreq = NULL; ce->__compareto = NULL; ce->create_object = NULL; ce->get_iterator = NULL; @@ -2161,8 +2156,6 @@ ZEND_API bool zend_is_smart_branch(const zend_op *opline) /* {{{ */ case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: - case ZEND_IS_LARGER: - case ZEND_IS_LARGER_OR_EQUAL: case ZEND_CASE: case ZEND_CASE_STRICT: case ZEND_ISSET_ISEMPTY_CV: @@ -8655,12 +8648,6 @@ void zend_compile_greater(znode *result, zend_ast *ast) /* {{{ */ return; } - if (left_node.op_type == IS_OBJECT || right_node.op_type == IS_OBJECT) { - zend_emit_op_tmp(result, - ast->kind == ZEND_AST_GREATER ? ZEND_IS_LARGER : ZEND_IS_LARGER_OR_EQUAL, - &left_node, &right_node); - } - zend_emit_op_tmp(result, ast->kind == ZEND_AST_GREATER ? ZEND_IS_SMALLER : ZEND_IS_SMALLER_OR_EQUAL, &right_node, &left_node); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index d545746eb7d7d..fcbc6f7e02053 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1112,11 +1112,6 @@ END_EXTERN_C() #define ZEND_MOD_FUNC_NAME "__mod" #define ZEND_POW_FUNC_NAME "__pow" #define ZEND_EQ_FUNC_NAME "__equals" -#define ZEND_NEQ_FUNC_NAME "__notequals" -#define ZEND_LT_FUNC_NAME "__lessthan" -#define ZEND_LTE_FUNC_NAME "__lessthanoreq" -#define ZEND_GT_FUNC_NAME "__greaterthan" -#define ZEND_GTE_FUNC_NAME "__greaterthanoreq" #define ZEND_COMPARE_FUNC_NAME "__compareto" /* The following constants may be combined in CG(compiler_options) diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 41daad57b28d4..656a5d88fea68 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -185,21 +185,6 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */ if (EXPECTED(!ce->__equals)) { ce->__equals = parent->__equals; } - if (EXPECTED(!ce->__notequals)) { - ce->__notequals = parent->__notequals; - } - if (EXPECTED(!ce->__lessthan)) { - ce->__lessthan = parent->__lessthan; - } - if (EXPECTED(!ce->__lessthanoreq)) { - ce->__lessthanoreq = parent->__lessthanoreq; - } - if (EXPECTED(!ce->__greaterthan)) { - ce->__greaterthan = parent->__greaterthan; - } - if (EXPECTED(!ce->__greaterthanoreq)) { - ce->__greaterthanoreq = parent->__greaterthanoreq; - } if (EXPECTED(!ce->__compareto)) { ce->__compareto = parent->__compareto; } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index cc832121fa6c1..5c9f80df60416 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -303,42 +303,6 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, operator = "!="; break; - case ZEND_IS_SMALLER: - if (zobj == Z_OBJ_P(op1)) { - fcic.function_handler = ce->__lessthan; - } else { - fcic.function_handler = ce->__greaterthan; - } - operator = "<"; - break; - - case ZEND_IS_SMALLER_OR_EQUAL: - if (zobj == Z_OBJ_P(op1)) { - fcic.function_handler = ce->__lessthanoreq; - } else { - fcic.function_handler = ce->__greaterthanoreq; - } - operator = "<="; - break; - - case ZEND_IS_LARGER: - if (zobj == Z_OBJ_P(op1)) { - fcic.function_handler = ce->__greaterthan; - } else { - fcic.function_handler = ce->__lessthan; - } - operator = ">"; - break; - - case ZEND_IS_LARGER_OR_EQUAL: - if (zobj == Z_OBJ_P(op1)) { - fcic.function_handler = ce->__greaterthanoreq; - } else { - fcic.function_handler = ce->__lessthanoreq; - } - operator = ">="; - break; - default: return FAILURE; } @@ -352,6 +316,18 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, continue; } + if ((Z_TYPE_P(op1) == IS_NULL || Z_TYPE_P(op2) == IS_NULL || + Z_TYPE_INFO_P(op1) == IS_FALSE || Z_TYPE_INFO_P(op2) == IS_FALSE) && + (opcode == ZEND_IS_EQUAL || opcode == ZEND_IS_NOT_EQUAL)) { + Z_TYPE_INFO_P(result) = IS_FALSE; + return SUCCESS; + } + + if ((Z_TYPE_P(op1) == IS_OBJECT && Z_OBJCE_P(op1)->ce_flags & ZEND_ACC_ENUM) || + (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJCE_P(op2)->ce_flags & ZEND_ACC_ENUM)) { + return FAILURE; + } + if (ce->type != ZEND_INTERNAL_CLASS) { zend_throw_exception_ex(zend_ce_operator_error, 0, "Operator '%s' unsupported by class %s", operator, ZSTR_VAL(ce->name)); } @@ -365,27 +341,6 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, fci.named_params = NULL; int tmp = zend_call_function(&fci, &fcic); - if (tmp == SUCCESS) { - switch (opcode) { - case ZEND_IS_NOT_EQUAL: - /* reverse __equals for not equals */ - Z_TYPE_INFO_P(result) = Z_TYPE_INFO_P(result) == IS_TRUE ? IS_FALSE : IS_TRUE; - break; - - case ZEND_IS_SMALLER: - case ZEND_IS_SMALLER_OR_EQUAL: - case ZEND_IS_LARGER: - case ZEND_IS_LARGER_OR_EQUAL: - if (is_retry) { - Z_LVAL_P(result) = Z_LVAL_P(result) * -1; - } - break; - - default: - break; - } - } - EG(fake_scope) = orig_fake_scope; return tmp; @@ -1744,23 +1699,26 @@ ZEND_API zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */ } /* }}} */ -static int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ +ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ { - zend_bool is_retry = 0; + zend_bool is_retry; zend_object *zobj; zend_class_entry *ce; if(Z_TYPE_P(o1) == IS_OBJECT) { zobj = Z_OBJ_P(o1); ce = Z_OBJCE_P(o1); + is_retry = 0; } else if(Z_TYPE_P(o2) == IS_OBJECT) { zobj = Z_OBJ_P(o2); ce = Z_OBJCE_P(o2); + is_retry = 1; } zend_fcall_info fci; zend_fcall_info_cache fcic; - zval *result = (result); + zval result; + int resultLval; zval params[1]; params[0] = *o2; @@ -1768,7 +1726,7 @@ static int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ fci.param_count = 1; fci.params = params; fci.size = sizeof(fci); - fci.retval = result; + fci.retval = &result; do { fci.object = zobj; @@ -1792,7 +1750,13 @@ static int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ int tmp = zend_call_function(&fci, &fcic); if (tmp == SUCCESS) { - return result->value.lval; + resultLval = Z_LVAL(result); + /* Normalize ints out of range for compare op */ + resultLval = (resultLval > 1 ? 1 : resultLval); + resultLval = (resultLval < -1 ? -1 : resultLval); + /* Reverse for right hand operand */ + resultLval = (is_retry ? resultLval*-1 : resultLval); + return resultLval; } else { return ZEND_UNCOMPARABLE; } diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 1e5d5df90f1c0..0ad5d1c57199d 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -1189,10 +1189,6 @@ ZEND_API binary_op_type get_binary_op(int opcode) return (binary_op_type) is_smaller_function; case ZEND_IS_SMALLER_OR_EQUAL: return (binary_op_type) is_smaller_or_equal_function; - case ZEND_IS_LARGER: - return (binary_op_type) is_larger_function; - case ZEND_IS_LARGER_OR_EQUAL: - return (binary_op_type) is_larger_or_equal_function; case ZEND_SPACESHIP: return (binary_op_type) compare_function; case ZEND_BW_OR: diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 1b15be57572cf..6c7598c3368a3 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2087,20 +2087,30 @@ static int compare_double_to_string(double dval, zend_string *str) /* {{{ */ } /* }}} */ -ZEND_API int ZEND_FASTCALL zend_equals_object(zval *op1, zval *op2) /* {{{ */ +ZEND_API int ZEND_FASTCALL zend_equals_object(zval *op1, zval *op2, zend_uchar equals) /* {{{ */ { zval ret; int retVal; + int result; if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_P(op1) == Z_OBJ_P(op2)) { return 0; } else if (Z_TYPE_P(op1) == IS_OBJECT) { - Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_IS_EQUAL, &ret, op1, op2); - retVal = (Z_TYPE_INFO(ret) == IS_TRUE ? 0 : 1); + result = Z_OBJ_HANDLER_P(op1, do_operation)(equals, &ret, op1, op2); + if (result == FAILURE) { + retVal = zend_compare(op1, op2); + } else { + retVal = (Z_TYPE_INFO(ret) == IS_TRUE ? 0 : 1); + } return retVal; } else { - Z_OBJ_HANDLER_P(op2, do_operation)(ZEND_IS_EQUAL, &ret, op1, op2); + result = Z_OBJ_HANDLER_P(op2, do_operation)(equals, &ret, op1, op2); + if (result == FAILURE) { + retVal = zend_compare(op1, op2); + } else { + retVal = (Z_TYPE_INFO(ret) == IS_TRUE ? 0 : 1); + } retVal = (Z_TYPE_INFO(ret) == IS_TRUE ? 0 : 1); return retVal; } diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 5b6e2361cadaf..cff5786ce31eb 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -425,7 +425,7 @@ static zend_always_inline bool i_zend_is_true(zval *op) // TODO: Use a different value to allow an actual distinction here. #define ZEND_UNCOMPARABLE 1 -ZEND_API int ZEND_FASTCALL zend_equals_object(zval *op1, zval *op2); +ZEND_API int ZEND_FASTCALL zend_equals_object(zval *op1, zval *op2, zend_uchar equals); ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2); ZEND_API zend_result ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index bfe2cf7bf415c..379541f4d20bc 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -581,7 +581,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_equal_hel op_2 = ZVAL_UNDEFINED_OP2(); } if (Z_TYPE_P(op_1) == IS_OBJECT || Z_TYPE_P(op_2) == IS_OBJECT) { - ret = zend_equals_object(op_1, op_2); + ret = zend_equals_object(op_1, op_2, ZEND_IS_EQUAL); } else { ret = zend_compare(op_1, op_2); } @@ -607,7 +607,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_not_equal op_2 = ZVAL_UNDEFINED_OP2(); } if (Z_TYPE_P(op_1) == IS_OBJECT || Z_TYPE_P(op_2) == IS_OBJECT) { - ret = zend_equals_object(op_1, op_2); + ret = zend_equals_object(op_1, op_2, ZEND_IS_NOT_EQUAL); } else { ret = zend_compare(op_1, op_2); } diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 8e8abb39ca0ae..83e409a9233c9 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -286,9 +286,7 @@ END_EXTERN_C() #define ZEND_FETCH_GLOBALS 200 #define ZEND_VERIFY_NEVER_TYPE 201 #define ZEND_CALLABLE_CONVERT 202 -#define ZEND_IS_LARGER 203 -#define ZEND_IS_LARGER_OR_EQUAL 204 -#define ZEND_VM_LAST_OPCODE 204 +#define ZEND_VM_LAST_OPCODE 202 #endif diff --git a/tests/lang/compare_objects_basic1.phpt b/tests/lang/compare_objects_basic1.phpt index 7df64e95c77d7..72f4f28eeee11 100644 --- a/tests/lang/compare_objects_basic1.phpt +++ b/tests/lang/compare_objects_basic1.phpt @@ -1,9 +1,9 @@ --TEST-- -Test standard 'compare' object handler +Test standard 'is_equal' object handler --FILE-- --EXPECT-- -Simple test for standard compare object handler +Simple test for standard is_equal object handler --- The following compare should return TRUE -- +-- The following is_equal should return TRUE -- bool(true) --- All the following compares should return FALSE -- -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) +-- All the following is_equals should throw InvalidOperator -- +InvalidOperator thrown +InvalidOperator thrown +InvalidOperator thrown +InvalidOperator thrown +InvalidOperator thrown +InvalidOperator thrown From 5fe2ad1339a6750d00acaced21bf9c619bbe51a3 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Fri, 20 Aug 2021 15:47:45 -0700 Subject: [PATCH 06/36] Fixing various comparison issues and making comparison optional --- Zend/tests/class_alias_001.phpt | 10 +--- Zend/tests/clone_002.phpt | 24 +++------ .../operator_overloads/equals_operator.phpt | 2 +- Zend/zend_object_handlers.c | 21 ++------ Zend/zend_operators.c | 1 - tests/lang/compare_objects_basic1.phpt | 52 +++++-------------- 6 files changed, 28 insertions(+), 82 deletions(-) diff --git a/Zend/tests/class_alias_001.phpt b/Zend/tests/class_alias_001.phpt index 05cdf43097329..371f08f80ba16 100644 --- a/Zend/tests/class_alias_001.phpt +++ b/Zend/tests/class_alias_001.phpt @@ -10,13 +10,7 @@ class_alias('foo', 'bar'); $a = new foo; $b = new bar; -try { - $a == $b; -} catch (InvalidOperator) { - echo "InvalidOperator thrown".PHP_EOL; -} - -var_dump($a === $b); +var_dump($a == $b, $a === $b); var_dump($a instanceof $b); var_dump($a instanceof foo); @@ -27,7 +21,7 @@ var_dump($b instanceof bar); ?> --EXPECT-- -InvalidOperator thrown +bool(true) bool(false) bool(true) bool(true) diff --git a/Zend/tests/clone_002.phpt b/Zend/tests/clone_002.phpt index aba1796fd74ff..0c958248d28e7 100644 --- a/Zend/tests/clone_002.phpt +++ b/Zend/tests/clone_002.phpt @@ -13,27 +13,15 @@ var_dump($a == $b, $b == $c); class foo { } $d = clone $a = $b = new foo; -try { - var_dump($a == $d); -} catch (InvalidOperator) { - echo "InvalidOperator thrown".PHP_EOL; -} -try { - var_dump($b == $d); -} catch (InvalidOperator) { - echo "InvalidOperator thrown".PHP_EOL; -} -try { - var_dump($c == $a); -} catch (InvalidOperator) { - echo "InvalidOperator thrown".PHP_EOL; -} +var_dump($a == $d); +var_dump($b == $d); +var_dump($c == $a); ?> --EXPECT-- bool(true) bool(true) bool(true) -InvalidOperator thrown -InvalidOperator thrown -InvalidOperator thrown +bool(true) +bool(true) +bool(false) diff --git a/Zend/tests/operator_overloads/equals_operator.phpt b/Zend/tests/operator_overloads/equals_operator.phpt index a7685ce90ee30..ac48c6cc0f1c5 100644 --- a/Zend/tests/operator_overloads/equals_operator.phpt +++ b/Zend/tests/operator_overloads/equals_operator.phpt @@ -1,5 +1,5 @@ --TEST-- -operator overload: div operator with scalars +operator overload: equals operator --FILE-- __equals; - operator = "=="; - break; - case ZEND_IS_NOT_EQUAL: fcic.function_handler = ce->__equals; - operator = "!="; break; default: @@ -316,15 +311,9 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, continue; } - if ((Z_TYPE_P(op1) == IS_NULL || Z_TYPE_P(op2) == IS_NULL || - Z_TYPE_INFO_P(op1) == IS_FALSE || Z_TYPE_INFO_P(op2) == IS_FALSE) && - (opcode == ZEND_IS_EQUAL || opcode == ZEND_IS_NOT_EQUAL)) { - Z_TYPE_INFO_P(result) = IS_FALSE; - return SUCCESS; - } - - if ((Z_TYPE_P(op1) == IS_OBJECT && Z_OBJCE_P(op1)->ce_flags & ZEND_ACC_ENUM) || - (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJCE_P(op2)->ce_flags & ZEND_ACC_ENUM)) { + if (opcode == ZEND_IS_EQUAL || opcode == ZEND_IS_NOT_EQUAL) { + /* For equality comparisons, return failure for all objects to */ + /* allow the normal override of the compare handler in extensions */ return FAILURE; } @@ -1709,7 +1698,7 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ zobj = Z_OBJ_P(o1); ce = Z_OBJCE_P(o1); is_retry = 0; - } else if(Z_TYPE_P(o2) == IS_OBJECT) { + } else { zobj = Z_OBJ_P(o2); ce = Z_OBJCE_P(o2); is_retry = 1; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 6c7598c3368a3..d1ffb74064c10 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2111,7 +2111,6 @@ ZEND_API int ZEND_FASTCALL zend_equals_object(zval *op1, zval *op2, zend_uchar e } else { retVal = (Z_TYPE_INFO(ret) == IS_TRUE ? 0 : 1); } - retVal = (Z_TYPE_INFO(ret) == IS_TRUE ? 0 : 1); return retVal; } } diff --git a/tests/lang/compare_objects_basic1.phpt b/tests/lang/compare_objects_basic1.phpt index 72f4f28eeee11..39a2c0d21461a 100644 --- a/tests/lang/compare_objects_basic1.phpt +++ b/tests/lang/compare_objects_basic1.phpt @@ -33,37 +33,13 @@ $obj5 = new class5(); echo "\n-- The following is_equal should return TRUE --\n"; var_dump($obj1 == $obj1); -echo "\n-- All the following is_equals should throw InvalidOperator --\n"; -try { - $obj1 == $obj2; -} catch (InvalidOperator) { - echo "InvalidOperator thrown".PHP_EOL; -} -try { - $obj1 == $obj3; -} catch (InvalidOperator) { - echo "InvalidOperator thrown".PHP_EOL; -} -try { - $obj1 == $obj4; -} catch (InvalidOperator) { - echo "InvalidOperator thrown".PHP_EOL; -} -try { - $obj1 == $obj5; -} catch (InvalidOperator) { - echo "InvalidOperator thrown".PHP_EOL; -} -try { - $obj4 == $obj3; -} catch (InvalidOperator) { - echo "InvalidOperator thrown".PHP_EOL; -} -try { - $obj5 == $obj3; -} catch (InvalidOperator) { - echo "InvalidOperator thrown".PHP_EOL; -} +echo "\n-- All the following is_equals should return FALSE --\n"; +var_dump($obj1 == $obj2); +var_dump($obj1 == $obj3); +var_dump($obj1 == $obj4); +var_dump($obj1 == $obj5); +var_dump($obj4 == $obj3); +var_dump($obj5 == $obj3); ?> --EXPECT-- @@ -72,10 +48,10 @@ Simple test for standard is_equal object handler -- The following is_equal should return TRUE -- bool(true) --- All the following is_equals should throw InvalidOperator -- -InvalidOperator thrown -InvalidOperator thrown -InvalidOperator thrown -InvalidOperator thrown -InvalidOperator thrown -InvalidOperator thrown +-- All the following is_equals should return FALSE -- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) From ff79f94d58119e9bbce1ecfaae452120ae00c90c Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Sun, 22 Aug 2021 00:56:38 -0700 Subject: [PATCH 07/36] Added bitwise operators and updated several tests --- .../operator_overloaded.phpt | 119 ++++++++++++++++++ Zend/zend.h | 6 + Zend/zend_API.c | 33 +++++ Zend/zend_compile.c | 6 + Zend/zend_compile.h | 9 ++ Zend/zend_inheritance.c | 18 +++ Zend/zend_object_handlers.c | 49 ++++++-- .../tests/math/pow_variation1_64bit.phpt | 2 +- ext/standard/tests/math/pow_variation2.phpt | 2 +- 9 files changed, 234 insertions(+), 10 deletions(-) create mode 100644 Zend/tests/operator_overloads/operator_overloaded.phpt diff --git a/Zend/tests/operator_overloads/operator_overloaded.phpt b/Zend/tests/operator_overloads/operator_overloaded.phpt new file mode 100644 index 0000000000000..01c37f70a858a --- /dev/null +++ b/Zend/tests/operator_overloads/operator_overloaded.phpt @@ -0,0 +1,119 @@ +--TEST-- +operator overload: overload called +--FILE-- +> 1; +1 >> $obj; +~$obj; + +?> +--EXPECT-- +__add() called +__add() called +__sub() called +__sub() called +__mul() called +__mul() called +__div() called +__div() called +__mod() called +__mod() called +__pow() called +__pow() called +__bitwiseAnd() called +__bitwiseAnd() called +__bitwiseOr() called +__bitwiseOr() called +__bitwiseXor() called +__bitwiseXor() called +__bitwiseShiftLeft() called +__bitwiseShiftLeft() called +__bitwiseShiftRight() called +__bitwiseShiftRight() called +__bitwiseNot() called diff --git a/Zend/zend.h b/Zend/zend.h index 4048d4774b2f5..4128a3730fa47 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -184,6 +184,12 @@ struct _zend_class_entry { zend_function *__div; zend_function *__mod; zend_function *__pow; + zend_function *__bitwiseand; + zend_function *__bitwiseor; + zend_function *__bitwisexor; + zend_function *__bitwisenot; + zend_function *__bitwiseshiftleft; + zend_function *__bitwiseshiftright; zend_function *__equals; zend_function *__compareto; diff --git a/Zend/zend_API.c b/Zend/zend_API.c index b8ce5d1f6d583..ba3987b49325d 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2504,6 +2504,15 @@ static void zend_check_magic_method_binary_operator_overload( zend_check_magic_method_arg_type(1, ce, fptr, error_type, MAY_BE_BOOL); } +static void zend_check_magic_method_unary_operator_overload( + const zend_class_entry *ce, const zend_function *fptr, int error_type) +{ + zend_check_magic_method_args(0, ce, fptr, error_type); + zend_check_magic_method_non_static(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_OBJECT); +} + static void zend_check_magic_method_comparison_operator_overload( const zend_class_entry *ce, const zend_function *fptr, int error_type) { @@ -2619,6 +2628,18 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); } else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) { zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWAND_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWOR_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWXOR_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWSL_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWSR_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) { + zend_check_magic_method_unary_operator_overload(ce, fptr, error_type); } else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) { zend_check_magic_method_comparison_operator_overload(ce, fptr, error_type); } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { @@ -2679,6 +2700,18 @@ ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, z ce->__mod = fptr; } else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) { ce->__pow = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_BWAND_FUNC_NAME)) { + ce->__bitwiseand = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_BWOR_FUNC_NAME)) { + ce->__bitwiseor = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_BWXOR_FUNC_NAME)) { + ce->__bitwisexor = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) { + ce->__bitwisenot = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_BWSL_FUNC_NAME)) { + ce->__bitwiseshiftleft = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_BWSR_FUNC_NAME)) { + ce->__bitwiseshiftright = fptr; } else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) { ce->__equals = fptr; } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 6d480f3c5a534..3b1dbafff2730 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1880,6 +1880,12 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, bool nullify_hand ce->__div = NULL; ce->__mod = NULL; ce->__pow = NULL; + ce->__bitwiseand = NULL; + ce->__bitwiseor = NULL; + ce->__bitwisexor = NULL; + ce->__bitwisenot = NULL; + ce->__bitwiseshiftleft = NULL; + ce->__bitwiseshiftright = NULL; ce->__equals = NULL; ce->__compareto = NULL; ce->create_object = NULL; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index fcbc6f7e02053..5fe917aa07f42 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1105,12 +1105,21 @@ END_EXTERN_C() /* operator overload functions */ +/* binary operators */ #define ZEND_ADD_FUNC_NAME "__add" #define ZEND_SUB_FUNC_NAME "__sub" #define ZEND_MUL_FUNC_NAME "__mul" #define ZEND_DIV_FUNC_NAME "__div" #define ZEND_MOD_FUNC_NAME "__mod" #define ZEND_POW_FUNC_NAME "__pow" +#define ZEND_BWAND_FUNC_NAME "__bitwiseand" +#define ZEND_BWOR_FUNC_NAME "__bitwiseor" +#define ZEND_BWXOR_FUNC_NAME "__bitwisexor" +#define ZEND_BWSL_FUNC_NAME "__bitwiseshiftleft" +#define ZEND_BWSR_FUNC_NAME "__bitwiseshiftright" +/* unary operators */ +#define ZEND_BWNOT_FUNC_NAME "__bitwisenot" +/* comparison operators */ #define ZEND_EQ_FUNC_NAME "__equals" #define ZEND_COMPARE_FUNC_NAME "__compareto" diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 656a5d88fea68..f468d7487b39e 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -182,6 +182,24 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */ if (EXPECTED(!ce->__pow)) { ce->__pow = parent->__pow; } + if (EXPECTED(!ce->__bitwiseand)) { + ce->__bitwiseand = parent->__bitwiseand; + } + if (EXPECTED(!ce->__bitwiseor)) { + ce->__bitwiseor = parent->__bitwiseor; + } + if (EXPECTED(!ce->__bitwisexor)) { + ce->__bitwisexor = parent->__bitwisexor; + } + if (EXPECTED(!ce->__bitwisenot)) { + ce->__bitwisenot = parent->__bitwisenot; + } + if (EXPECTED(!ce->__bitwiseshiftleft)) { + ce->__bitwiseshiftleft = parent->__bitwiseshiftleft; + } + if (EXPECTED(!ce->__bitwiseshiftright)) { + ce->__bitwiseshiftright = parent->__bitwiseshiftright; + } if (EXPECTED(!ce->__equals)) { ce->__equals = parent->__equals; } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 8c51ee22745d6..f38a2044fe15a 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -243,7 +243,6 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, zval params[2]; zval left; - fci.param_count = 2; fci.size = sizeof(fci); fci.retval = result; @@ -252,16 +251,20 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, Z_TYPE_INFO(left) = is_retry ? IS_FALSE : IS_TRUE; - if (zobj == Z_OBJ_P(op1)) { - ZVAL_COPY_VALUE(¶ms[0], op2); - ZVAL_COPY_VALUE(¶ms[1], &left); + if (op2 == NULL) { + fci.param_count = 0; } else { - ZVAL_COPY_VALUE(¶ms[0], op1); - ZVAL_COPY_VALUE(¶ms[1], &left); + fci.param_count = 2; + if (zobj == Z_OBJ_P(op1)) { + ZVAL_COPY_VALUE(¶ms[0], op2); + ZVAL_COPY_VALUE(¶ms[1], &left); + } else { + ZVAL_COPY_VALUE(¶ms[0], op1); + ZVAL_COPY_VALUE(¶ms[1], &left); + } + fci.params = params; } - fci.params = params; - switch (opcode) { case ZEND_ADD: fcic.function_handler = ce->__add; @@ -293,6 +296,36 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, operator = "**"; break; + case ZEND_BW_AND: + fcic.function_handler = ce->__bitwiseand; + operator = "&"; + break; + + case ZEND_BW_OR: + fcic.function_handler = ce->__bitwiseor; + operator = "|"; + break; + + case ZEND_BW_XOR: + fcic.function_handler = ce->__bitwisexor; + operator = "^"; + break; + + case ZEND_BW_NOT: + fcic.function_handler = ce->__bitwisenot; + operator = "~"; + break; + + case ZEND_SL: + fcic.function_handler = ce->__bitwiseshiftleft; + operator = "<<"; + break; + + case ZEND_SR: + fcic.function_handler = ce->__bitwiseshiftright; + operator = ">>"; + break; + case ZEND_IS_EQUAL: case ZEND_IS_NOT_EQUAL: fcic.function_handler = ce->__equals; diff --git a/ext/standard/tests/math/pow_variation1_64bit.phpt b/ext/standard/tests/math/pow_variation1_64bit.phpt index 5869e905f067c..f6fd1bd096ad4 100644 --- a/ext/standard/tests/math/pow_variation1_64bit.phpt +++ b/ext/standard/tests/math/pow_variation1_64bit.phpt @@ -159,7 +159,7 @@ Unsupported operand types: string ** int Unsupported operand types: string ** int -- Iteration 23 -- -Unsupported operand types: classA ** int +Operator '**' unsupported by class classA -- Iteration 24 -- int(0) diff --git a/ext/standard/tests/math/pow_variation2.phpt b/ext/standard/tests/math/pow_variation2.phpt index 9351dbd4ce738..00d28dc286b45 100644 --- a/ext/standard/tests/math/pow_variation2.phpt +++ b/ext/standard/tests/math/pow_variation2.phpt @@ -155,7 +155,7 @@ Unsupported operand types: float ** string Unsupported operand types: float ** string -- Iteration 23 -- -Unsupported operand types: float ** classA +Operator '**' unsupported by class classA -- Iteration 24 -- float(1) From 88bd5504de4d54ec5427b67da456cdd21d88dfe3 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Fri, 26 Nov 2021 13:03:25 -0800 Subject: [PATCH 08/36] Interim commit --- .gitignore | 7 +++++ Zend/zend_ast.c | 20 ++------------ Zend/zend_ast.h | 2 -- Zend/zend_compile.c | 52 ------------------------------------- Zend/zend_language_parser.y | 4 +-- Zend/zend_opcode.c | 4 +++ Zend/zend_operators.c | 4 +-- Zend/zend_vm_execute.h | 44 +++++++++++++++++++++++++++++++ Zend/zend_vm_opcodes.c | 8 ++++-- Zend/zend_vm_opcodes.h | 4 ++- 10 files changed, 70 insertions(+), 79 deletions(-) diff --git a/.gitignore b/.gitignore index 78dcc1f7ac2ff..afd62e46b5b01 100644 --- a/.gitignore +++ b/.gitignore @@ -286,3 +286,10 @@ tmp-php.ini !/ext/fileinfo/magicdata.patch !/ext/pcre/pcre2lib/config.h !/win32/build/Makefile + +# ------- +# Special cases to not be merged +# ------- + +.idea +compile_commands.json diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 59f8c968b18b1..94ec3d1cce629 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -524,22 +524,6 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast zval_ptr_dtor_nogc(&op2); } break; - case ZEND_AST_GREATER: - case ZEND_AST_GREATER_EQUAL: - if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { - ret = FAILURE; - } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) { - zval_ptr_dtor_nogc(&op1); - ret = FAILURE; - } else { - /* op1 > op2 is the same as op2 < op1 */ - binary_op_type op = ast->kind == ZEND_AST_GREATER - ? is_smaller_function : is_smaller_or_equal_function; - ret = op(result, &op2, &op1); - zval_ptr_dtor_nogc(&op1); - zval_ptr_dtor_nogc(&op2); - } - break; case ZEND_AST_UNARY_OP: if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { ret = FAILURE; @@ -2009,14 +1993,14 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_IS_NOT_EQUAL: BINARY_OP(" != ", 170, 171, 171); case ZEND_IS_SMALLER: BINARY_OP(" < ", 180, 181, 181); case ZEND_IS_SMALLER_OR_EQUAL: BINARY_OP(" <= ", 180, 181, 181); + case ZEND_IS_LARGER: BINARY_OP(" > ", 180, 181, 181); + case ZEND_IS_LARGER_OR_EQUAL: BINARY_OP(" >= ", 180, 181, 181); case ZEND_POW: BINARY_OP(" ** ", 250, 251, 250); case ZEND_BOOL_XOR: BINARY_OP(" xor ", 40, 40, 41); case ZEND_SPACESHIP: BINARY_OP(" <=> ", 180, 181, 181); EMPTY_SWITCH_DEFAULT_CASE(); } break; - case ZEND_AST_GREATER: BINARY_OP(" > ", 180, 181, 181); - case ZEND_AST_GREATER_EQUAL: BINARY_OP(" >= ", 180, 181, 181); case ZEND_AST_AND: BINARY_OP(" && ", 130, 130, 131); case ZEND_AST_OR: BINARY_OP(" || ", 120, 120, 121); case ZEND_AST_ARRAY_ELEM: diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 86f153580063c..dd4c9445b3c88 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -119,8 +119,6 @@ enum _zend_ast_kind { ZEND_AST_ASSIGN_REF, ZEND_AST_ASSIGN_OP, ZEND_AST_BINARY_OP, - ZEND_AST_GREATER, - ZEND_AST_GREATER_EQUAL, ZEND_AST_AND, ZEND_AST_OR, ZEND_AST_ARRAY_ELEM, diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 3b1dbafff2730..ace894f20dc1f 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -8405,14 +8405,6 @@ static inline bool zend_try_ct_eval_unary_pm(zval *result, zend_ast_kind kind, z } /* }}} */ -static inline void zend_ct_eval_greater(zval *result, zend_ast_kind kind, zval *op1, zval *op2) /* {{{ */ -{ - binary_op_type fn = kind == ZEND_AST_GREATER - ? is_smaller_function : is_smaller_or_equal_function; - fn(result, op2, op1); -} -/* }}} */ - static bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ { zend_ast_list *list = zend_ast_get_list(ast); @@ -8632,34 +8624,6 @@ void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -/* We do not use zend_compile_binary_op for this because we want to retain the left-to-right - * evaluation order. */ -void zend_compile_greater(znode *result, zend_ast *ast) /* {{{ */ -{ - zend_ast *left_ast = ast->child[0]; - zend_ast *right_ast = ast->child[1]; - znode left_node, right_node; - - ZEND_ASSERT(ast->kind == ZEND_AST_GREATER || ast->kind == ZEND_AST_GREATER_EQUAL); - - zend_compile_expr(&left_node, left_ast); - zend_compile_expr(&right_node, right_ast); - - if (left_node.op_type == IS_CONST && right_node.op_type == IS_CONST) { - result->op_type = IS_CONST; - zend_ct_eval_greater(&result->u.constant, ast->kind, - &left_node.u.constant, &right_node.u.constant); - zval_ptr_dtor(&left_node.u.constant); - zval_ptr_dtor(&right_node.u.constant); - return; - } - - zend_emit_op_tmp(result, - ast->kind == ZEND_AST_GREATER ? ZEND_IS_SMALLER : ZEND_IS_SMALLER_OR_EQUAL, - &right_node, &left_node); -} -/* }}} */ - void zend_compile_unary_op(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; @@ -9652,7 +9616,6 @@ void zend_compile_magic_const(znode *result, zend_ast *ast) /* {{{ */ bool zend_is_allowed_in_const_expr(zend_ast_kind kind) /* {{{ */ { return kind == ZEND_AST_ZVAL || kind == ZEND_AST_BINARY_OP - || kind == ZEND_AST_GREATER || kind == ZEND_AST_GREATER_EQUAL || kind == ZEND_AST_AND || kind == ZEND_AST_OR || kind == ZEND_AST_UNARY_OP || kind == ZEND_AST_UNARY_PLUS || kind == ZEND_AST_UNARY_MINUS @@ -10075,10 +10038,6 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ case ZEND_AST_BINARY_OP: zend_compile_binary_op(result, ast); return; - case ZEND_AST_GREATER: - case ZEND_AST_GREATER_EQUAL: - zend_compile_greater(result, ast); - return; case ZEND_AST_UNARY_OP: zend_compile_unary_op(result, ast); return; @@ -10272,17 +10231,6 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */ return; } break; - case ZEND_AST_GREATER: - case ZEND_AST_GREATER_EQUAL: - zend_eval_const_expr(&ast->child[0]); - zend_eval_const_expr(&ast->child[1]); - if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) { - return; - } - - zend_ct_eval_greater(&result, ast->kind, - zend_ast_get_zval(ast->child[0]), zend_ast_get_zval(ast->child[1])); - break; case ZEND_AST_AND: case ZEND_AST_OR: { diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index a8bddfae50a3e..65280f3143808 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -1155,9 +1155,9 @@ expr: | expr T_IS_SMALLER_OR_EQUAL expr { $$ = zend_ast_create_binary_op(ZEND_IS_SMALLER_OR_EQUAL, $1, $3); } | expr '>' expr - { $$ = zend_ast_create(ZEND_AST_GREATER, $1, $3); } + { $$ = zend_ast_create_binary_op(ZEND_IS_LARGER, $1, $3); } | expr T_IS_GREATER_OR_EQUAL expr - { $$ = zend_ast_create(ZEND_AST_GREATER_EQUAL, $1, $3); } + { $$ = zend_ast_create_binary_op(ZEND_IS_LARGER_OR_EQUAL, $1, $3); } | expr T_SPACESHIP expr { $$ = zend_ast_create_binary_op(ZEND_SPACESHIP, $1, $3); } | expr T_INSTANCEOF class_name_reference diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 0ad5d1c57199d..1e5d5df90f1c0 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -1189,6 +1189,10 @@ ZEND_API binary_op_type get_binary_op(int opcode) return (binary_op_type) is_smaller_function; case ZEND_IS_SMALLER_OR_EQUAL: return (binary_op_type) is_smaller_or_equal_function; + case ZEND_IS_LARGER: + return (binary_op_type) is_larger_function; + case ZEND_IS_LARGER_OR_EQUAL: + return (binary_op_type) is_larger_or_equal_function; case ZEND_SPACESHIP: return (binary_op_type) compare_function; case ZEND_BW_OR: diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index d1ffb74064c10..6564d2f9c2c0a 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2330,14 +2330,14 @@ ZEND_API zend_result ZEND_FASTCALL is_smaller_or_equal_function(zval *result, zv ZEND_API zend_result ZEND_FASTCALL is_larger_function(zval *result, zval *op1, zval *op2) /* {{{ */ { - ZVAL_BOOL(result, (zend_compare(op1, op2) < 0)); + ZVAL_BOOL(result, (zend_compare(op1, op2) > 0)); return SUCCESS; } /* }}} */ ZEND_API zend_result ZEND_FASTCALL is_larger_or_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */ { - ZVAL_BOOL(result, (zend_compare(op1, op2) <= 0)); + ZVAL_BOOL(result, (zend_compare(op1, op2) >= 0)); return SUCCESS; } /* }}} */ diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 379541f4d20bc..7b855e1a863db 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -664,6 +664,50 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_smaller_o ZEND_VM_SMART_BRANCH(ret <= 0, 1); } +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_larger_helper_SPEC(zval *op_1, zval *op_2 ZEND_OPCODE_HANDLER_ARGS_DC) +{ + int ret; + USE_OPLINE + + SAVE_OPLINE(); + if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) { + op_1 = ZVAL_UNDEFINED_OP1(); + } + if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) { + op_2 = ZVAL_UNDEFINED_OP2(); + } + ret = zend_compare(op_1, op_2); + if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(op_1); + } + if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(op_2); + } + ZEND_VM_SMART_BRANCH(ret > 0, 1); +} + +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_larger_or_equal_helper_SPEC(zval *op_1, zval *op_2 ZEND_OPCODE_HANDLER_ARGS_DC) +{ + int ret; + USE_OPLINE + + SAVE_OPLINE(); + if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) { + op_1 = ZVAL_UNDEFINED_OP1(); + } + if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) { + op_2 = ZVAL_UNDEFINED_OP2(); + } + ret = zend_compare(op_1, op_2); + if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(op_1); + } + if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(op_2); + } + ZEND_VM_SMART_BRANCH(ret >= 0, 1); +} + static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_bw_or_helper_SPEC(zval *op_1, zval *op_2 ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 7f88f9e84b690..e98a0722b1957 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -22,7 +22,7 @@ #include #include -static const char *zend_vm_opcodes_names[203] = { +static const char *zend_vm_opcodes_names[205] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -226,9 +226,11 @@ static const char *zend_vm_opcodes_names[203] = { "ZEND_FETCH_GLOBALS", "ZEND_VERIFY_NEVER_TYPE", "ZEND_CALLABLE_CONVERT", + "ZEND_IS_LARGER", + "ZEND_IS_LARGER_OR_EQUAL" }; -static uint32_t zend_vm_opcodes_flags[203] = { +static uint32_t zend_vm_opcodes_flags[205] = { 0x00000000, 0x00000b0b, 0x00000b0b, @@ -432,6 +434,8 @@ static uint32_t zend_vm_opcodes_flags[203] = { 0x00000101, 0x00000101, 0x00000101, + 0x00000b0b, + 0x00000b0b, }; ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(zend_uchar opcode) { diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 83e409a9233c9..79ae503d12622 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -286,7 +286,9 @@ END_EXTERN_C() #define ZEND_FETCH_GLOBALS 200 #define ZEND_VERIFY_NEVER_TYPE 201 #define ZEND_CALLABLE_CONVERT 202 +#define ZEND_IS_LARGER 203 +#define ZEND_IS_LARGER_OR_EQUAL 204 -#define ZEND_VM_LAST_OPCODE 202 +#define ZEND_VM_LAST_OPCODE 204 #endif From 2fa6d98a6bebad069d87d3cfbb64d479d1bea1b9 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Fri, 26 Nov 2021 21:06:32 -0800 Subject: [PATCH 09/36] Improvements to operator overloads and IS_LARGER opcode --- Zend/Optimizer/block_pass.c | 40 +- Zend/Optimizer/dce.c | 2 + Zend/Optimizer/dfa_pass.c | 2 + Zend/Optimizer/pass1.c | 2 + Zend/Optimizer/sccp.c | 2 + Zend/Optimizer/zend_inference.c | 40 + Zend/Optimizer/zend_optimizer.c | 4 + Zend/Optimizer/zend_ssa.c | 40 +- Zend/zend_compile.c | 30 +- Zend/zend_object_handlers.c | 14 +- Zend/zend_operators.c | 22 +- Zend/zend_vm_def.h | 182 ++ Zend/zend_vm_execute.h | 2582 ++++++++++++++++- Zend/zend_vm_handlers.h | 1266 ++++---- Zend/zend_vm_opcodes.c | 2 +- Zend/zend_vm_opcodes.h | 4 +- .../lang/operators/nan-comparison-false.phpt | 16 + 17 files changed, 3647 insertions(+), 603 deletions(-) diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index eac6d6b37aa73..96d3e744c3f8f 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -505,16 +505,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array break; case ZEND_IS_SMALLER: if (opline->opcode == ZEND_BOOL_NOT) { - zend_uchar tmp_type; - uint32_t tmp; - - src->opcode = ZEND_IS_SMALLER_OR_EQUAL; - tmp_type = src->op1_type; - src->op1_type = src->op2_type; - src->op2_type = tmp_type; - tmp = src->op1.num; - src->op1.num = src->op2.num; - src->op2.num = tmp; + src->opcode = ZEND_IS_LARGER_OR_EQUAL; } COPY_NODE(src->result, opline->result); SET_VAR_SOURCE(src); @@ -523,16 +514,25 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array break; case ZEND_IS_SMALLER_OR_EQUAL: if (opline->opcode == ZEND_BOOL_NOT) { - zend_uchar tmp_type; - uint32_t tmp; - + src->opcode = ZEND_IS_LARGER; + } + COPY_NODE(src->result, opline->result); + SET_VAR_SOURCE(src); + MAKE_NOP(opline); + ++(*opt_count); + break; + case ZEND_IS_LARGER: + if (opline->opcode == ZEND_BOOL_NOT) { + src->opcode = ZEND_IS_SMALLER_OR_EQUAL; + } + COPY_NODE(src->result, opline->result); + SET_VAR_SOURCE(src); + MAKE_NOP(opline); + ++(*opt_count); + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (opline->opcode == ZEND_BOOL_NOT) { src->opcode = ZEND_IS_SMALLER; - tmp_type = src->op1_type; - src->op1_type = src->op2_type; - src->op2_type = tmp_type; - tmp = src->op1.num; - src->op1.num = src->op2.num; - src->op2.num = tmp; } COPY_NODE(src->result, opline->result); SET_VAR_SOURCE(src); @@ -820,6 +820,8 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array case ZEND_SR: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_IS_IDENTICAL: case ZEND_IS_NOT_IDENTICAL: case ZEND_BOOL_XOR: diff --git a/Zend/Optimizer/dce.c b/Zend/Optimizer/dce.c index 2dbea214e47bf..4ed080c2795cb 100644 --- a/Zend/Optimizer/dce.c +++ b/Zend/Optimizer/dce.c @@ -105,6 +105,8 @@ static inline bool may_have_side_effects( case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_CASE: case ZEND_CASE_STRICT: case ZEND_CAST: diff --git a/Zend/Optimizer/dfa_pass.c b/Zend/Optimizer/dfa_pass.c index 406ff625dc249..c81acf4171548 100644 --- a/Zend/Optimizer/dfa_pass.c +++ b/Zend/Optimizer/dfa_pass.c @@ -1173,6 +1173,8 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx || opline->opcode == ZEND_IS_NOT_EQUAL || opline->opcode == ZEND_IS_SMALLER || opline->opcode == ZEND_IS_SMALLER_OR_EQUAL + || opline->opcode == ZEND_IS_LARGER + || opline->opcode == ZEND_IS_LARGER_OR_EQUAL ) { if (opline->op1_type == IS_CONST && opline->op2_type != IS_CONST) { diff --git a/Zend/Optimizer/pass1.c b/Zend/Optimizer/pass1.c index 3579ea1c6bfc8..9fe275b26e3f5 100644 --- a/Zend/Optimizer/pass1.c +++ b/Zend/Optimizer/pass1.c @@ -76,6 +76,8 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_IS_IDENTICAL: case ZEND_IS_NOT_IDENTICAL: case ZEND_BOOL_XOR: diff --git a/Zend/Optimizer/sccp.c b/Zend/Optimizer/sccp.c index be82c5aba91d6..9da902ba7c40c 100644 --- a/Zend/Optimizer/sccp.c +++ b/Zend/Optimizer/sccp.c @@ -1365,6 +1365,8 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_IS_IDENTICAL: case ZEND_IS_NOT_IDENTICAL: case ZEND_BW_OR: diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 92958baf22b94..5c083e1b6e3d3 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -1238,6 +1238,42 @@ ZEND_API bool zend_inference_propagate_range(const zend_op_array *op_array, zend } } break; + case ZEND_IS_LARGER: + if (ssa_op->result_def == var) { + if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) { + op1_min = OP1_MIN_RANGE(); + op2_min = OP2_MIN_RANGE(); + op1_max = OP1_MAX_RANGE(); + op2_max = OP2_MAX_RANGE(); + + tmp->min = op1_max > op2_min; + tmp->max = op1_min > op2_max; + return 1; + } else { + tmp->min = 0; + tmp->max = 1; + return 1; + } + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (ssa_op->result_def == var) { + if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) { + op1_min = OP1_MIN_RANGE(); + op2_min = OP2_MIN_RANGE(); + op1_max = OP1_MAX_RANGE(); + op2_max = OP2_MAX_RANGE(); + + tmp->min = op1_max >= op2_min; + tmp->max = op1_min >= op2_max; + return 1; + } else { + tmp->min = 0; + tmp->max = 1; + return 1; + } + } + break; case ZEND_QM_ASSIGN: case ZEND_JMP_SET: case ZEND_COALESCE: @@ -2492,6 +2528,8 @@ static zend_always_inline zend_result _zend_update_type_info( case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_INSTANCEOF: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: @@ -4742,6 +4780,8 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_CASE: case ZEND_SPACESHIP: if ((t1 & MAY_BE_ANY) == MAY_BE_NULL diff --git a/Zend/Optimizer/zend_optimizer.c b/Zend/Optimizer/zend_optimizer.c index ebc76017c6024..23e1b62c26533 100644 --- a/Zend/Optimizer/zend_optimizer.c +++ b/Zend/Optimizer/zend_optimizer.c @@ -1110,6 +1110,8 @@ static void zend_redo_pass_two(zend_op_array *op_array) case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_CASE: case ZEND_CASE_STRICT: case ZEND_ISSET_ISEMPTY_CV: @@ -1233,6 +1235,8 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa) case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_CASE: case ZEND_CASE_STRICT: case ZEND_ISSET_ISEMPTY_CV: diff --git a/Zend/Optimizer/zend_ssa.c b/Zend/Optimizer/zend_ssa.c index 3642070c53fe7..838dc461a3419 100644 --- a/Zend/Optimizer/zend_ssa.c +++ b/Zend/Optimizer/zend_ssa.c @@ -296,7 +296,9 @@ static void place_essa_pis( ((opline-1)->opcode == ZEND_IS_EQUAL || (opline-1)->opcode == ZEND_IS_NOT_EQUAL || (opline-1)->opcode == ZEND_IS_SMALLER || - (opline-1)->opcode == ZEND_IS_SMALLER_OR_EQUAL) && + (opline-1)->opcode == ZEND_IS_SMALLER_OR_EQUAL || + (opline-1)->opcode == ZEND_IS_LARGER || + (opline-1)->opcode == ZEND_IS_LARGER_OR_EQUAL) && opline->op1.var == (opline-1)->result.var) { int var1 = -1; int var2 = -1; @@ -405,6 +407,24 @@ static void place_essa_pis( pi_range_min(pi, var2, val2+1); } } + } else if ((opline-1)->opcode == ZEND_IS_LARGER) { + if (val2 > ZEND_LONG_MIN) { + if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var1))) { + pi_range_min(pi, var2, val2-1); + } + } + if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var1))) { + pi_range_max(pi, var2, val2); + } + } else if ((opline-1)->opcode == ZEND_IS_LARGER_OR_EQUAL) { + if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var1))) { + pi_range_min(pi, var2, val2); + } + if (val2 < ZEND_LONG_MAX) { + if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var1))) { + pi_range_max(pi, var2, val2+1); + } + } } } if (var2 >= 0) { @@ -440,6 +460,24 @@ static void place_essa_pis( pi_range_max(pi, var1, val1-1); } } + } else if ((opline-1)->opcode == ZEND_IS_LARGER) { + if (val1 < ZEND_LONG_MAX) { + if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var2))) { + pi_range_max(pi, var1, val1+1); + } + } + if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var2))) { + pi_range_min(pi, var1, val1); + } + } else if ((opline-1)->opcode == ZEND_IS_LARGER_OR_EQUAL) { + if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var2))) { + pi_range_max(pi, var1, val1); + } + if (val1 > ZEND_LONG_MIN) { + if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var2))) { + pi_range_min(pi, var1, val1-1); + } + } } } } else if (opline->op1_type == IS_TMP_VAR && diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index b020306a48725..5382615d95771 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2087,6 +2087,8 @@ ZEND_API bool zend_is_smart_branch(const zend_op *opline) /* {{{ */ case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_CASE: case ZEND_CASE_STRICT: case ZEND_ISSET_ISEMPTY_CV: @@ -8568,34 +8570,6 @@ static void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -/* We do not use zend_compile_binary_op for this because we want to retain the left-to-right - * evaluation order. */ -static void zend_compile_greater(znode *result, zend_ast *ast) /* {{{ */ -{ - zend_ast *left_ast = ast->child[0]; - zend_ast *right_ast = ast->child[1]; - znode left_node, right_node; - - ZEND_ASSERT(ast->kind == ZEND_AST_GREATER || ast->kind == ZEND_AST_GREATER_EQUAL); - - zend_compile_expr(&left_node, left_ast); - zend_compile_expr(&right_node, right_ast); - - if (left_node.op_type == IS_CONST && right_node.op_type == IS_CONST) { - result->op_type = IS_CONST; - zend_ct_eval_greater(&result->u.constant, ast->kind, - &left_node.u.constant, &right_node.u.constant); - zval_ptr_dtor(&left_node.u.constant); - zval_ptr_dtor(&right_node.u.constant); - return; - } - - zend_emit_op_tmp(result, - ast->kind == ZEND_AST_GREATER ? ZEND_IS_SMALLER : ZEND_IS_SMALLER_OR_EQUAL, - &right_node, &left_node); -} -/* }}} */ - void zend_compile_unary_op(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 49355c507f859..ea53f1d3aaad2 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -340,7 +340,10 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, if(zobj == Z_OBJ_P(op1) && Z_TYPE_P(op2) == IS_OBJECT && !is_retry) { zobj = Z_OBJ_P(op2); ce = Z_OBJCE_P(op2); + Z_TYPE_INFO(left) = IS_FALSE; is_retry = 1; + ZVAL_COPY_VALUE(¶ms[0], op1); + ZVAL_COPY_VALUE(¶ms[1], &left); continue; } @@ -1741,20 +1744,22 @@ ZEND_API zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ { - zend_bool is_retry; + zend_bool is_retry = 0; zend_object *zobj; zend_class_entry *ce; if(Z_TYPE_P(o1) == IS_OBJECT) { zobj = Z_OBJ_P(o1); ce = Z_OBJCE_P(o1); - is_retry = 0; } else { zobj = Z_OBJ_P(o2); ce = Z_OBJCE_P(o2); is_retry = 1; } + zend_class_entry *orig_fake_scope = EG(fake_scope); + EG(fake_scope) = NULL; + zend_fcall_info fci; zend_fcall_info_cache fcic; zval result; @@ -1764,7 +1769,6 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ params[0] = *o2; fci.param_count = 1; - fci.params = params; fci.size = sizeof(fci); fci.retval = &result; @@ -1777,6 +1781,7 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ if(zobj == Z_OBJ_P(o1) && Z_TYPE_P(o2) == IS_OBJECT && !is_retry) { zobj = Z_OBJ_P(o2); ce = Z_OBJCE_P(o2); + params[0] = *o1; is_retry = 1; continue; } @@ -1784,11 +1789,14 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ return zend_std_compare_objects(o1, o2); } + fci.params = params; fcic.called_scope = ce; fcic.object = zobj; fcic.function_handler->type = ZEND_USER_FUNCTION; int tmp = zend_call_function(&fci, &fcic); + EG(fake_scope) = orig_fake_scope; + if (tmp == SUCCESS) { resultLval = Z_LVAL(result); /* Normalize ints out of range for compare op */ diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index b0c77565a305f..5fbfdda65a3ce 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -118,7 +118,7 @@ ZEND_API const unsigned char zend_toupper_map[256] = { 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef, -0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff +0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff }; @@ -2375,6 +2375,16 @@ ZEND_API zend_result ZEND_FASTCALL is_smaller_or_equal_function(zval *result, zv ZEND_API zend_result ZEND_FASTCALL is_larger_function(zval *result, zval *op1, zval *op2) /* {{{ */ { + if (Z_TYPE_P(op1) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op1))) { + ZVAL_BOOL(result, false); + return SUCCESS; + } + + if (Z_TYPE_P(op2) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op2))) { + ZVAL_BOOL(result, false); + return SUCCESS; + } + ZVAL_BOOL(result, (zend_compare(op1, op2) > 0)); return SUCCESS; } @@ -2382,6 +2392,16 @@ ZEND_API zend_result ZEND_FASTCALL is_larger_function(zval *result, zval *op1, z ZEND_API zend_result ZEND_FASTCALL is_larger_or_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */ { + if (Z_TYPE_P(op1) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op1))) { + ZVAL_BOOL(result, false); + return SUCCESS; + } + + if (Z_TYPE_P(op2) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op2))) { + ZVAL_BOOL(result, false); + return SUCCESS; + } + ZVAL_BOOL(result, (zend_compare(op1, op2) >= 0)); return SUCCESS; } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 65f17983fb034..8943929a048bc 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -783,6 +783,140 @@ ZEND_VM_C_LABEL(is_smaller_or_equal_double): ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper, op_1, op1, op_2, op2); } +ZEND_VM_HELPER(zend_is_larger_helper, ANY, ANY, zval *op_1, zval *op_2) +{ + int ret; + USE_OPLINE + + SAVE_OPLINE(); + if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) { + op_1 = ZVAL_UNDEFINED_OP1(); + } + if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) { + op_2 = ZVAL_UNDEFINED_OP2(); + } + ret = zend_compare(op_1, op_2); + if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(op_1); + } + if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(op_2); + } + ZEND_VM_SMART_BRANCH(ret > 0, 1); +} + +ZEND_VM_HOT_NOCONSTCONST_HANDLER(203, ZEND_IS_LARGER, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH)) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) > Z_LVAL_P(op2))) { + ZEND_VM_C_LABEL(is_larger_true): + ZEND_VM_SMART_BRANCH_TRUE(); + } else { + ZEND_VM_C_LABEL(is_larger_false): + ZEND_VM_SMART_BRANCH_FALSE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + ZEND_VM_C_GOTO(is_larger_double); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + ZEND_VM_C_LABEL(is_larger_double): + if (d1 > d2) { + ZEND_VM_C_GOTO(is_larger_true); + } else { + ZEND_VM_C_GOTO(is_larger_false); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + ZEND_VM_C_GOTO(is_larger_double); + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_larger_helper, op_1, op1, op_2, op2); +} + +ZEND_VM_HELPER(zend_is_larger_or_equal_helper, ANY, ANY, zval *op_1, zval *op_2) +{ + int ret; + USE_OPLINE + + SAVE_OPLINE(); + if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) { + op_1 = ZVAL_UNDEFINED_OP1(); + } + if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) { + op_2 = ZVAL_UNDEFINED_OP2(); + } + ret = zend_compare(op_1, op_2); + if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(op_1); + } + if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(op_2); + } + ZEND_VM_SMART_BRANCH(ret >= 0, 1); +} + +ZEND_VM_HOT_NOCONSTCONST_HANDLER(204, ZEND_IS_LARGER_OR_EQUAL, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH)) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + if (ZEND_VM_SPEC && OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) >= Z_LVAL_P(op2))) { + ZEND_VM_C_LABEL(is_larger_or_equal_true): + ZEND_VM_SMART_BRANCH_TRUE(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { + ZEND_VM_C_LABEL(is_larger_or_equal_false): + ZEND_VM_SMART_BRANCH_FALSE(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + ZEND_VM_C_GOTO(is_larger_or_equal_double); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + ZEND_VM_C_LABEL(is_larger_or_equal_double): + if (d1 >= d2) { + ZEND_VM_C_GOTO(is_larger_or_equal_true); + } else { + ZEND_VM_C_GOTO(is_larger_or_equal_false); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + ZEND_VM_C_GOTO(is_larger_or_equal_double); + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_larger_or_equal_helper, op_1, op1, op_2, op2); +} + ZEND_VM_COLD_CONSTCONST_HANDLER(170, ZEND_SPACESHIP, CONST|TMPVAR|CV, CONST|TMPVAR|CV) { USE_OPLINE @@ -9537,6 +9671,54 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER_OR_EQUAL, (op1_info == MAY_BE_DOUB ZEND_VM_SMART_BRANCH(result, 0); } +ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_LARGER, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_LARGER_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST)) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = (Z_LVAL_P(op1) > Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH(result, 0); +} + +ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_LARGER, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_LARGER_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST)) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = (Z_DVAL_P(op1) > Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH(result, 0); +} + +ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_LARGER_OR_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_LARGER_OR_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST)) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = (Z_LVAL_P(op1) >= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH(result, 0); +} + +ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_LARGER_OR_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_LARGER_OR_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST)) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = (Z_DVAL_P(op1) >= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH(result, 0); +} + ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_PRE_INC_LONG_NO_OVERFLOW, CV, ANY, SPEC(RETVAL)) { USE_OPLINE diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 8d2fe03ba213c..17748835b3bf8 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -580,11 +580,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_equal_hel if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) { op_2 = ZVAL_UNDEFINED_OP2(); } - if (Z_TYPE_P(op_1) == IS_OBJECT || Z_TYPE_P(op_2) == IS_OBJECT) { - ret = zend_equals_object(op_1, op_2, ZEND_IS_EQUAL); - } else { - ret = zend_compare(op_1, op_2); - } + ret = zend_compare(op_1, op_2); if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_nogc(op_1); } @@ -606,11 +602,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_not_equal if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) { op_2 = ZVAL_UNDEFINED_OP2(); } - if (Z_TYPE_P(op_1) == IS_OBJECT || Z_TYPE_P(op_2) == IS_OBJECT) { - ret = zend_equals_object(op_1, op_2, ZEND_IS_NOT_EQUAL); - } else { - ret = zend_compare(op_1, op_2); - } + ret = zend_compare(op_1, op_2); if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_nogc(op_1); } @@ -6110,6 +6102,96 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQU ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) > Z_LVAL_P(op2))) { + is_larger_true: + ZEND_VM_SMART_BRANCH_TRUE(); + } else { + is_larger_false: + ZEND_VM_SMART_BRANCH_FALSE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_double: + if (d1 > d2) { + goto is_larger_true; + } else { + goto is_larger_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) >= Z_LVAL_P(op2))) { + is_larger_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { + is_larger_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_or_equal_double: + if (d1 >= d2) { + goto is_larger_or_equal_true; + } else { + goto is_larger_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_or_equal_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -8173,6 +8255,276 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) > Z_LVAL_P(op2))) { + is_larger_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { + is_larger_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_double: + if (d1 > d2) { + goto is_larger_true; + } else { + goto is_larger_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) > Z_LVAL_P(op2))) { + is_larger_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { + is_larger_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_double: + if (d1 > d2) { + goto is_larger_true; + } else { + goto is_larger_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) > Z_LVAL_P(op2))) { + is_larger_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { + is_larger_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_double: + if (d1 > d2) { + goto is_larger_true; + } else { + goto is_larger_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) >= Z_LVAL_P(op2))) { + is_larger_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { + is_larger_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_or_equal_double: + if (d1 >= d2) { + goto is_larger_or_equal_true; + } else { + goto is_larger_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_or_equal_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) >= Z_LVAL_P(op2))) { + is_larger_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { + is_larger_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_or_equal_double: + if (d1 >= d2) { + goto is_larger_or_equal_true; + } else { + goto is_larger_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_or_equal_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) >= Z_LVAL_P(op2))) { + is_larger_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { + is_larger_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_or_equal_double: + if (d1 >= d2) { + goto is_larger_or_equal_true; + } else { + goto is_larger_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_or_equal_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -8353,6 +8705,150 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) > Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) > Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) > Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) > Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) > Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) > Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) >= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) >= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) >= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) >= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) >= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) >= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -12628,6 +13124,276 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) > Z_LVAL_P(op2))) { + is_larger_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { + is_larger_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_double: + if (d1 > d2) { + goto is_larger_true; + } else { + goto is_larger_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) > Z_LVAL_P(op2))) { + is_larger_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { + is_larger_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_double: + if (d1 > d2) { + goto is_larger_true; + } else { + goto is_larger_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) > Z_LVAL_P(op2))) { + is_larger_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { + is_larger_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_double: + if (d1 > d2) { + goto is_larger_true; + } else { + goto is_larger_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) >= Z_LVAL_P(op2))) { + is_larger_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { + is_larger_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_or_equal_double: + if (d1 >= d2) { + goto is_larger_or_equal_true; + } else { + goto is_larger_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_or_equal_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) >= Z_LVAL_P(op2))) { + is_larger_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { + is_larger_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_or_equal_double: + if (d1 >= d2) { + goto is_larger_or_equal_true; + } else { + goto is_larger_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_or_equal_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) >= Z_LVAL_P(op2))) { + is_larger_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { + is_larger_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_or_equal_double: + if (d1 >= d2) { + goto is_larger_or_equal_true; + } else { + goto is_larger_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_or_equal_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -13194,6 +13960,150 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) > Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) > Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) > Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) > Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) > Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) > Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) >= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) >= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) >= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) >= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) >= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) >= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -13648,6 +14558,276 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) > Z_LVAL_P(op2))) { + is_larger_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { + is_larger_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_double: + if (d1 > d2) { + goto is_larger_true; + } else { + goto is_larger_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) > Z_LVAL_P(op2))) { + is_larger_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { + is_larger_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_double: + if (d1 > d2) { + goto is_larger_true; + } else { + goto is_larger_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) > Z_LVAL_P(op2))) { + is_larger_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { + is_larger_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_double: + if (d1 > d2) { + goto is_larger_true; + } else { + goto is_larger_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) >= Z_LVAL_P(op2))) { + is_larger_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { + is_larger_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_or_equal_double: + if (d1 >= d2) { + goto is_larger_or_equal_true; + } else { + goto is_larger_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_or_equal_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) >= Z_LVAL_P(op2))) { + is_larger_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { + is_larger_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_or_equal_double: + if (d1 >= d2) { + goto is_larger_or_equal_true; + } else { + goto is_larger_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_or_equal_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) >= Z_LVAL_P(op2))) { + is_larger_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { + is_larger_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_larger_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); + is_larger_or_equal_double: + if (d1 >= d2) { + goto is_larger_or_equal_true; + } else { + goto is_larger_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_larger_or_equal_double; + } + } + ZEND_VM_TAIL_CALL(zend_is_larger_or_equal_helper_SPEC(op1, op2 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -14100,6 +15280,150 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) > Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) > Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) > Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) > Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) > Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) > Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) >= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) >= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) >= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) >= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) >= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) >= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -53600,6 +54924,156 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_CONST_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_CONST_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_CONST_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_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_IS_LARGER_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_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_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, (void*)&&ZEND_RECV_NOTYPE_SPEC_LABEL, (void*)&&ZEND_JMP_FORWARD_SPEC_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -54437,6 +55911,306 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_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_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_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_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_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_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_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_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, + (void*)&&ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, (void*)&&ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_LABEL, (void*)&&ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_LABEL, (void*)&&ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED_LABEL, @@ -55264,6 +57038,14 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST) ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_SPEC_CONST_CONST): + VM_TRACE(ZEND_IS_LARGER_SPEC_CONST_CONST) + ZEND_IS_LARGER_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST) + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_SPACESHIP_SPEC_CONST_CONST): VM_TRACE(ZEND_SPACESHIP_SPEC_CONST_CONST) ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -55432,6 +57214,30 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ) ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_SPEC_CONST_TMPVARCV): + VM_TRACE(ZEND_IS_LARGER_SPEC_CONST_TMPVARCV) + ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ): + VM_TRACE(ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ) + ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ) + ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV) + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ) + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ) + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV): VM_TRACE(ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -55492,6 +57298,54 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV): + VM_TRACE(ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV) + ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ): + VM_TRACE(ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ) + ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) + ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV): + VM_TRACE(ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV) + ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ): + VM_TRACE(ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) + ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) + ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV): VM_TRACE(ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -55824,6 +57678,30 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ) ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_SPEC_TMPVARCV_CONST): + VM_TRACE(ZEND_IS_LARGER_SPEC_TMPVARCV_CONST) + ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ): + VM_TRACE(ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ) + ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ) + ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST) + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ) + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ) + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_BW_OR_SPEC_TMPVARCV_CONST): VM_TRACE(ZEND_BW_OR_SPEC_TMPVARCV_CONST) ZEND_BW_OR_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -55984,6 +57862,54 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST): + VM_TRACE(ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST) + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ): + VM_TRACE(ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ) + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST): + VM_TRACE(ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST) + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ): + VM_TRACE(ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_ADD_SPEC_TMPVARCV_TMPVARCV): VM_TRACE(ZEND_ADD_SPEC_TMPVARCV_TMPVARCV) ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -56032,6 +57958,30 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ) ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV): + VM_TRACE(ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV) + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ): + VM_TRACE(ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ) + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ) + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV) + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ) + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ) + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV): VM_TRACE(ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV) ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -56176,6 +58126,54 @@ ZEND_API void execute_ex(zend_execute_data *ex) VM_TRACE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV): + VM_TRACE(ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV) + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ): + VM_TRACE(ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV): + VM_TRACE(ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ): + VM_TRACE(ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + VM_TRACE(ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR): VM_TRACE(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -61645,6 +63643,156 @@ void zend_vm_init(void) ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_HANDLER, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED_HANDLER, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_IS_LARGER_SPEC_CONST_CONST_HANDLER, + ZEND_IS_LARGER_SPEC_CONST_CONST_HANDLER, + ZEND_IS_LARGER_SPEC_CONST_CONST_HANDLER, + ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_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_IS_LARGER_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_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_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, ZEND_RECV_NOTYPE_SPEC_HANDLER, ZEND_JMP_FORWARD_SPEC_HANDLER, ZEND_NULL_HANDLER, @@ -62482,6 +64630,306 @@ void zend_vm_init(void) ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_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_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_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_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_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_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_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_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_HANDLER, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_HANDLER, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED_HANDLER, @@ -62754,7 +65202,9 @@ void zend_vm_init(void) 2547, 2548, 2549, - 3453 + 2550 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH, + 2625 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH, + 3903 }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -62927,7 +65377,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2552 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2702 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -62935,7 +65385,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2577 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2727 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -62943,7 +65393,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2602 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2752 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -62954,17 +65404,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2627 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2777 | 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 = 2652 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2802 | 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 = 2677 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2827 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -62975,17 +65425,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2702 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2852 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } 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 = 2727 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2877 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } 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 = 2752 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2902 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_IDENTICAL: @@ -62996,14 +65446,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2777 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2927 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } 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 = 2852 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3002 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3077 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3227 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_IDENTICAL: @@ -63014,14 +65464,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2927 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3077 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } 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 = 3002 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3152 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3082 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3232 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_EQUAL: @@ -63032,12 +65482,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2777 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2927 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } 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 = 2852 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3002 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_EQUAL: @@ -63048,12 +65498,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2927 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3077 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } 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 = 3002 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3152 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_SMALLER: @@ -63061,12 +65511,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3087 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3237 | 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 = 3162 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3312 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -63074,74 +65524,74 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3237 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3387 | 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 = 3312 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3462 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_LONG) { - spec = 3399 | SPEC_RULE_OP1; + spec = 3849 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_DOUBLE) { - spec = 3404 | SPEC_RULE_OP1; + spec = 3854 | SPEC_RULE_OP1; } else if ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) { - spec = 3409 | SPEC_RULE_OP1; + spec = 3859 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3387 | SPEC_RULE_RETVAL; + spec = 3837 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3389 | SPEC_RULE_RETVAL; + spec = 3839 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3391 | SPEC_RULE_RETVAL; + spec = 3841 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3393 | SPEC_RULE_RETVAL; + spec = 3843 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3395; + spec = 3845; } else if (op1_info == MAY_BE_LONG) { - spec = 3396; + spec = 3846; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3397; + spec = 3847; } else if (op1_info == MAY_BE_LONG) { - spec = 3398; + spec = 3848; } break; case ZEND_JMP: if (OP_JMP_ADDR(op, op->op1) > op) { - spec = 2551; + spec = 2701; } break; case ZEND_RECV: if (op->op2.num == MAY_BE_ANY) { - spec = 2550; + spec = 2700; } break; case ZEND_SEND_VAL: if (op->op1_type == IS_CONST && op->op2_type == IS_UNUSED && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3449; + spec = 3899; } break; case ZEND_SEND_VAR_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3444 | SPEC_RULE_OP1; + spec = 3894 | SPEC_RULE_OP1; } break; case ZEND_FE_FETCH_R: if (op->op2_type == IS_CV && (op1_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 3451 | SPEC_RULE_RETVAL; + spec = 3901 | SPEC_RULE_RETVAL; } break; case ZEND_FETCH_DIM_R: @@ -63149,17 +65599,43 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3414 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3864 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_SEND_VAL_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3450; + spec = 3900; } break; case ZEND_SEND_VAR: if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3439 | SPEC_RULE_OP1; + spec = 3889 | SPEC_RULE_OP1; + } + break; + case ZEND_IS_LARGER: + if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { + if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { + break; + } + spec = 3537 | 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 = 3612 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { + if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { + break; + } + spec = 3687 | 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 = 3762 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_BW_OR: diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index a5796187e11be..eedc3e1564a9b 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -1355,498 +1355,774 @@ _(2547, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \ _(2548, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \ _(2549, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \ - _(2550, ZEND_RECV_NOTYPE_SPEC) \ - _(2551, ZEND_JMP_FORWARD_SPEC) \ - _(2557, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2558, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2559, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2561, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2562, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2563, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2564, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2566, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2572, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2573, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2574, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2576, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2582, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2583, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2584, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2586, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2587, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2588, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2589, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2591, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2597, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2598, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2599, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2601, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2607, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2608, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2609, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2611, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2612, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2613, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2614, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2616, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2622, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2623, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2624, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2626, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2628, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2629, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2631, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2632, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2633, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2634, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2636, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2637, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2638, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2639, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2641, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2647, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2648, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2649, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2651, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2653, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2654, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2656, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2657, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2658, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2659, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2661, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2662, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2663, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2664, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2666, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2672, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2673, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2674, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2676, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2678, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2679, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2681, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2682, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2683, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2684, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2686, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2687, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2688, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2689, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2691, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2697, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2698, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2699, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2701, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2707, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2708, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2709, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2711, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2712, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2713, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2714, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2716, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2722, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2723, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2724, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2726, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2732, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2733, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2734, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2736, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2737, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2738, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2739, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2741, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2747, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2748, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2749, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2751, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2757, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2758, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2759, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2761, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2762, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2763, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2764, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2766, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2772, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2773, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2774, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2776, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2792, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2793, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2794, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2795, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2796, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2797, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2798, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2799, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2800, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2804, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2805, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2806, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2807, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2808, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2809, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2810, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2811, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2812, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2813, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2814, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2815, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2819, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2820, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2821, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2837, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2841, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2849, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2850, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2851, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2867, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2868, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2869, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2870, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2871, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2872, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2873, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2874, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2875, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2879, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2880, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2881, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2882, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2883, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2884, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2885, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2886, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2887, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2888, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2889, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2890, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2894, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2895, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2896, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2912, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2916, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2924, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2925, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2926, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2942, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2943, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2944, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2945, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2946, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2947, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2948, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2949, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2950, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2954, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2955, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2956, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2957, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2958, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2959, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2960, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2961, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2962, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2963, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2964, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2965, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2969, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2970, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2971, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2987, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2991, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2999, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3000, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3001, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3017, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3018, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3019, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3020, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3021, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3022, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3023, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3024, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3025, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3029, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3030, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3031, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3032, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3033, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3034, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3035, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3036, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3037, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3038, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3039, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3040, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3044, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3045, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3046, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3062, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3066, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3074, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3075, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3076, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3077, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3081, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3082, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3086, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3090, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3091, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3092, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3093, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3094, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3095, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3099, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3100, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3101, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3102, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3103, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3104, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3105, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3106, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3107, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3108, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3109, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3110, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3114, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3115, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3116, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3117, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3118, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3119, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3120, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3121, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3122, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3123, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3124, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3125, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3129, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3130, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3131, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3153, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3159, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3160, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3161, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3165, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3166, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3167, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3168, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3169, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3170, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3174, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3175, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3176, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3177, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3178, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3179, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3180, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3181, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3182, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3183, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3184, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3185, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3189, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3190, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3191, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3192, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3193, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3194, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3195, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3196, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3197, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3198, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3204, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3206, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3228, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3234, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3235, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3236, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3240, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3241, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3242, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3243, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3244, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3245, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3249, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3250, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3251, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3252, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3253, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3254, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3255, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3256, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3257, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3258, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3259, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3260, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3264, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3265, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3266, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3267, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3268, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3269, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3270, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3271, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3272, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3273, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3279, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3281, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3303, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3309, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3310, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3311, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3315, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3316, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3317, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3318, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3319, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3320, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3324, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3325, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3326, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3327, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3328, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3329, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3330, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3331, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3332, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3333, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3334, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3335, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3339, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3340, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3341, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3342, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3343, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3344, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3345, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3346, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3347, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3348, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3354, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3356, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3378, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3384, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3385, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3386, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3387, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3388, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3389, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3390, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ - _(3391, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3392, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3393, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3394, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ - _(3395, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3396, ZEND_POST_INC_LONG_SPEC_CV) \ - _(3397, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3398, ZEND_POST_DEC_LONG_SPEC_CV) \ - _(3399, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ - _(3400, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3401, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3403, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3404, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ - _(3405, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3406, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3408, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3409, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ - _(3410, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3411, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3413, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3415, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3416, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3418, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3419, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ - _(3420, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3421, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3423, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3424, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ - _(3425, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3426, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3428, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3434, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ - _(3435, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3436, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3438, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3441, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ - _(3443, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ - _(3446, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ - _(3448, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ - _(3449, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ - _(3450, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ - _(3451, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ - _(3452, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ - _(3452+1, ZEND_NULL) + _(2550, ZEND_IS_LARGER_SPEC_CONST_CONST) \ + _(2551, ZEND_IS_LARGER_SPEC_CONST_CONST) \ + _(2552, ZEND_IS_LARGER_SPEC_CONST_CONST) \ + _(2553, ZEND_IS_LARGER_SPEC_CONST_TMPVARCV) \ + _(2554, ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ) \ + _(2555, ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(2556, ZEND_IS_LARGER_SPEC_CONST_TMPVARCV) \ + _(2557, ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ) \ + _(2558, ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(2562, ZEND_IS_LARGER_SPEC_CONST_TMPVARCV) \ + _(2563, ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPZ) \ + _(2564, ZEND_IS_LARGER_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(2565, ZEND_IS_LARGER_SPEC_TMPVARCV_CONST) \ + _(2566, ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2567, ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2568, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV) \ + _(2569, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2570, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2571, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV) \ + _(2572, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2573, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2577, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV) \ + _(2578, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2579, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2580, ZEND_IS_LARGER_SPEC_TMPVARCV_CONST) \ + _(2581, ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2582, ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2583, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV) \ + _(2584, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2585, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2586, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV) \ + _(2587, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2588, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2592, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV) \ + _(2593, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2594, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2610, ZEND_IS_LARGER_SPEC_TMPVARCV_CONST) \ + _(2611, ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2612, ZEND_IS_LARGER_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2613, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV) \ + _(2614, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2615, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2616, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV) \ + _(2617, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2618, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2622, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV) \ + _(2623, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2624, ZEND_IS_LARGER_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2625, ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST) \ + _(2626, ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST) \ + _(2627, ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_CONST) \ + _(2628, ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV) \ + _(2629, ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ) \ + _(2630, ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(2631, ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV) \ + _(2632, ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ) \ + _(2633, ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(2637, ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV) \ + _(2638, ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ) \ + _(2639, ZEND_IS_LARGER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(2640, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST) \ + _(2641, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2642, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2643, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV) \ + _(2644, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2645, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2646, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV) \ + _(2647, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2648, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2652, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV) \ + _(2653, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2654, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2655, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST) \ + _(2656, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2657, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2658, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV) \ + _(2659, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2660, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2661, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV) \ + _(2662, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2663, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2667, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV) \ + _(2668, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2669, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2685, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST) \ + _(2686, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2687, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2688, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV) \ + _(2689, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2690, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2691, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV) \ + _(2692, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2693, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2697, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV) \ + _(2698, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2699, ZEND_IS_LARGER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2700, ZEND_RECV_NOTYPE_SPEC) \ + _(2701, ZEND_JMP_FORWARD_SPEC) \ + _(2707, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2708, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2709, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2711, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2712, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2713, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2714, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2716, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2722, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2723, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2724, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2726, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2732, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2733, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2734, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2736, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2737, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2738, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2739, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2741, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2747, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2748, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2749, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2751, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2757, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2758, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2759, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2761, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2762, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2763, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2764, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2766, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2772, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2773, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2774, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2776, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2778, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2779, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2781, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2782, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2783, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2784, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2786, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2787, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2788, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2789, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2791, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2797, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2798, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2799, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2801, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2803, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2804, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2806, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2807, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2808, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2809, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2811, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2812, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2813, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2814, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2816, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2822, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2823, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2824, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2826, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2828, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2829, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2831, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2832, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2833, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2834, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2836, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2837, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2838, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2839, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2841, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2847, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2848, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2849, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2851, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2857, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2858, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2859, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2861, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2862, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2863, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2864, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2866, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2872, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2873, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2874, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2876, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2882, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2883, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2884, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2886, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2887, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2888, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2889, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2891, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2897, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2898, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2899, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2901, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2907, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2908, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2909, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2911, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2912, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2913, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2914, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2916, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2922, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2923, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2924, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2926, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2942, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2943, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2944, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2945, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2946, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2947, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2948, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2949, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2950, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2954, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2955, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2956, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2957, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2958, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2959, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2960, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2961, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2962, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2963, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2964, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2965, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2969, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2970, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2971, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2987, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2988, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2989, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2990, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2991, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2992, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2993, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2994, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2995, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2999, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3000, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3001, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3017, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3018, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3019, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3020, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3021, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3022, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3023, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3024, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3025, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3029, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3030, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3031, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3032, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3033, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3034, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3035, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3036, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3037, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3038, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3039, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3040, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3044, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3045, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3046, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3062, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3063, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3064, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3065, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3066, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3067, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3068, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3069, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3070, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3074, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3075, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3076, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3092, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3093, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3094, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3095, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3096, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3097, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3098, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3099, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3100, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3104, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3105, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3106, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3107, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3108, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3109, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3110, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3111, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3112, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3113, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3114, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3115, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3119, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3120, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3121, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3137, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3138, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3139, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3140, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3141, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3142, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3143, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3144, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3145, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3149, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3150, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3151, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3167, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3168, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3169, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3170, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3171, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3172, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3173, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3174, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3175, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3179, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3180, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3181, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3182, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3183, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3184, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3185, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3186, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3187, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3188, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3189, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3190, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3194, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3195, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3196, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3212, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3213, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3214, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3215, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3216, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3217, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3218, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3219, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3220, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3224, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3225, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3226, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3227, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3231, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3232, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3236, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3240, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3241, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3242, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3243, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3244, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3245, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3249, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3250, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3251, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3252, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3253, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3254, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3255, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3256, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3257, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3258, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3259, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3260, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3264, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3265, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3266, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3267, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3268, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3269, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3270, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3271, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3272, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3273, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3274, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3275, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3279, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3280, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3281, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3297, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3298, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3299, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3300, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3301, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3302, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3303, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3304, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3305, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3309, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3310, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3311, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3315, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3316, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3317, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3318, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3319, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3320, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3324, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3325, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3326, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3327, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3328, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3329, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3330, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3331, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3332, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3333, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3334, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3335, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3339, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3340, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3341, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3342, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3343, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3344, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3345, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3346, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3347, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3348, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3349, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3350, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3354, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3355, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3356, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3372, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3373, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3374, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3375, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3376, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3377, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3378, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3379, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3380, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3384, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3385, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3386, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3390, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3391, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3392, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3393, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3394, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3395, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3399, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3400, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3401, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3402, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3403, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3404, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3405, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3406, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3407, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3408, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3409, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3410, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3414, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3415, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3416, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3417, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3418, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3419, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3420, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3421, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3422, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3423, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3424, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3425, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3429, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3430, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3431, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3447, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3448, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3449, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3450, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3451, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3452, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3453, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3454, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3455, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3459, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3460, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3461, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3465, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3466, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3467, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3468, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3469, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3470, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3474, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3475, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3476, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3477, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3478, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3479, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3480, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3481, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3482, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3483, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3484, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3485, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3489, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3490, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3491, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3492, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3493, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3494, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3495, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3496, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3497, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3498, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3499, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3500, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3504, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3505, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3506, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3522, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3523, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3524, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3525, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3526, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3527, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3528, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3529, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3530, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3534, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3535, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3536, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3540, ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV) \ + _(3541, ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3542, ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3543, ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV) \ + _(3544, ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3545, ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3549, ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV) \ + _(3550, ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3551, ZEND_IS_LARGER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3552, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST) \ + _(3553, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3554, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3555, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3556, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3557, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3558, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3559, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3560, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3564, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3565, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3566, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3567, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST) \ + _(3568, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3569, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3570, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3571, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3572, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3573, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3574, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3575, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3579, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3580, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3581, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3597, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST) \ + _(3598, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3599, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3600, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3601, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3602, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3603, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3604, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3605, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3609, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3610, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3611, ZEND_IS_LARGER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3615, ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3616, ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3617, ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3618, ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3619, ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3620, ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3624, ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3625, ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3626, ZEND_IS_LARGER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3627, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3628, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3629, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3630, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3631, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3632, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3633, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3634, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3635, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3639, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3640, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3641, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3642, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3643, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3644, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3645, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3646, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3647, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3648, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3649, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3650, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3654, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3655, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3656, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3672, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3673, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3674, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3675, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3676, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3677, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3678, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3679, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3680, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3684, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3685, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3686, ZEND_IS_LARGER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3690, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3691, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3692, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3693, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3694, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3695, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3699, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3700, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3701, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3702, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3703, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3704, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3705, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3706, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3707, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3708, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3709, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3710, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3714, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3715, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3716, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3717, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3718, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3719, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3720, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3721, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3722, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3723, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3724, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3725, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3729, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3730, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3731, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3747, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3748, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3749, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3750, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3751, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3752, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3753, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3754, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3755, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3759, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3760, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3761, ZEND_IS_LARGER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3765, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3766, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3767, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3768, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3769, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3770, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3774, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3775, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3776, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3777, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3778, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3779, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3780, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3781, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3782, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3783, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3784, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3785, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3789, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3790, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3791, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3792, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3793, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3794, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3795, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3796, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3797, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3798, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3799, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3800, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3804, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3805, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3806, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3822, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3823, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3824, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3825, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3826, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3827, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3828, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3829, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3830, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3834, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3835, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3836, ZEND_IS_LARGER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3837, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3838, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3839, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3840, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ + _(3841, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3842, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3843, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3844, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ + _(3845, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3846, ZEND_POST_INC_LONG_SPEC_CV) \ + _(3847, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3848, ZEND_POST_DEC_LONG_SPEC_CV) \ + _(3849, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ + _(3850, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3851, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3853, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3854, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ + _(3855, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3856, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3858, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3859, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ + _(3860, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3861, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3863, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3865, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3866, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3868, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3869, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3870, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3871, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3873, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3874, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3875, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3876, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3878, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3884, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3885, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3886, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3888, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3891, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ + _(3893, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ + _(3896, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ + _(3898, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ + _(3899, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ + _(3900, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ + _(3901, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ + _(3902, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ + _(3902+1, ZEND_NULL) diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index e98a0722b1957..c48538e2c4a05 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -227,7 +227,7 @@ static const char *zend_vm_opcodes_names[205] = { "ZEND_VERIFY_NEVER_TYPE", "ZEND_CALLABLE_CONVERT", "ZEND_IS_LARGER", - "ZEND_IS_LARGER_OR_EQUAL" + "ZEND_IS_LARGER_OR_EQUAL", }; static uint32_t zend_vm_opcodes_flags[205] = { diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 79ae503d12622..8e8abb39ca0ae 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -286,8 +286,8 @@ END_EXTERN_C() #define ZEND_FETCH_GLOBALS 200 #define ZEND_VERIFY_NEVER_TYPE 201 #define ZEND_CALLABLE_CONVERT 202 -#define ZEND_IS_LARGER 203 -#define ZEND_IS_LARGER_OR_EQUAL 204 +#define ZEND_IS_LARGER 203 +#define ZEND_IS_LARGER_OR_EQUAL 204 #define ZEND_VM_LAST_OPCODE 204 diff --git a/tests/lang/operators/nan-comparison-false.phpt b/tests/lang/operators/nan-comparison-false.phpt index 1bb1f7b23dcbf..c66d07a8fd99a 100644 --- a/tests/lang/operators/nan-comparison-false.phpt +++ b/tests/lang/operators/nan-comparison-false.phpt @@ -8,6 +8,10 @@ var_dump(0 < NAN); var_dump(0 <= NAN); var_dump(0 > NAN); var_dump(0 >= NAN); +var_dump(NAN < 0); +var_dump(NAN <= 0); +var_dump(NAN > 0); +var_dump(NAN >= 0); echo "** VAR\n"; $nan = NAN; @@ -15,6 +19,10 @@ var_dump(0 < $nan); var_dump(0 <= $nan); var_dump(0 > $nan); var_dump(0 >= $nan); +var_dump($nan < 0); +var_dump($nan <= 0); +var_dump($nan > 0); +var_dump($nan >= 0); ?> --EXPECT-- ** CONST @@ -22,8 +30,16 @@ bool(false) bool(false) bool(false) bool(false) +bool(false) +bool(false) +bool(false) +bool(false) ** VAR bool(false) bool(false) bool(false) bool(false) +bool(false) +bool(false) +bool(false) +bool(false) From a2c3f159e835a3b9983845c781aee8037e7c2241 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Mon, 29 Nov 2021 00:25:57 -0800 Subject: [PATCH 10/36] Fixing some bugs --- Zend/zend_object_handlers.c | 2 +- Zend/zend_operators.c | 64 +++++++++++++++++++++++++++++++++---- Zend/zend_operators.h | 8 ++--- Zend/zend_vm_def.h | 25 ++++++++++++--- Zend/zend_vm_execute.h | 25 ++++++++++++--- 5 files changed, 104 insertions(+), 20 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index ea53f1d3aaad2..e7653dcd0865a 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -251,7 +251,7 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, Z_TYPE_INFO(left) = is_retry ? IS_FALSE : IS_TRUE; - if (op2 == NULL) { + if (op2 == NULL || opcode == ZEND_BW_NOT) { fci.param_count = 0; } else { fci.param_count = 2; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 5fbfdda65a3ce..c72d2f0610b03 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2220,14 +2220,14 @@ ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */ case TYPE_PAIR(IS_DOUBLE, IS_STRING): if (zend_isnan(Z_DVAL_P(op1))) { - return 1; + return ZEND_UNCOMPARABLE; } return compare_double_to_string(Z_DVAL_P(op1), Z_STR_P(op2)); case TYPE_PAIR(IS_STRING, IS_DOUBLE): if (zend_isnan(Z_DVAL_P(op2))) { - return 1; + return ZEND_UNCOMPARABLE; } return -compare_double_to_string(Z_DVAL_P(op2), Z_STR_P(op1)); @@ -2361,14 +2361,50 @@ ZEND_API zend_result ZEND_FASTCALL is_not_equal_function(zval *result, zval *op1 ZEND_API zend_result ZEND_FASTCALL is_smaller_function(zval *result, zval *op1, zval *op2) /* {{{ */ { - ZVAL_BOOL(result, (zend_compare(op1, op2) < 0)); + if (Z_TYPE_P(op1) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op1))) { + ZVAL_BOOL(result, false); + return SUCCESS; + } + + if (Z_TYPE_P(op2) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op2))) { + ZVAL_BOOL(result, false); + return SUCCESS; + } + + int intResult; + intResult = zend_compare(op1, op2); + + if (intResult > 1) { + ZVAL_BOOL(result, false); + return SUCCESS; + } + + ZVAL_BOOL(result, (intResult < 0)); return SUCCESS; } /* }}} */ ZEND_API zend_result ZEND_FASTCALL is_smaller_or_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */ { - ZVAL_BOOL(result, (zend_compare(op1, op2) <= 0)); + if (Z_TYPE_P(op1) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op1))) { + ZVAL_BOOL(result, false); + return SUCCESS; + } + + if (Z_TYPE_P(op2) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op2))) { + ZVAL_BOOL(result, false); + return SUCCESS; + } + + int intResult; + intResult = zend_compare(op1, op2); + + if (intResult > 1) { + ZVAL_BOOL(result, false); + return SUCCESS; + } + + ZVAL_BOOL(result, (intResult <= 0)); return SUCCESS; } /* }}} */ @@ -2385,7 +2421,15 @@ ZEND_API zend_result ZEND_FASTCALL is_larger_function(zval *result, zval *op1, z return SUCCESS; } - ZVAL_BOOL(result, (zend_compare(op1, op2) > 0)); + int intResult; + intResult = zend_compare(op1, op2); + + if (intResult > 1) { + ZVAL_BOOL(result, false); + return SUCCESS; + } + + ZVAL_BOOL(result, (intResult > 0)); return SUCCESS; } /* }}} */ @@ -2402,7 +2446,15 @@ ZEND_API zend_result ZEND_FASTCALL is_larger_or_equal_function(zval *result, zva return SUCCESS; } - ZVAL_BOOL(result, (zend_compare(op1, op2) >= 0)); + int intResult; + intResult = zend_compare(op1, op2); + + if (intResult > 1) { + ZVAL_BOOL(result, false); + return SUCCESS; + } + + ZVAL_BOOL(result, (intResult >= 0)); return SUCCESS; } /* }}} */ diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 80fc04344224c..cf218cb181327 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -419,11 +419,9 @@ static zend_always_inline bool i_zend_is_true(zval *op) return result; } -/* Indicate that two values cannot be compared. This value should be returned for both orderings - * of the operands. This implies that all of ==, <, <= and >, >= will return false, because we - * canonicalize >/>= to 1 which should always + * result in (bool)false. */ +#define ZEND_UNCOMPARABLE 2 ZEND_API int ZEND_FASTCALL zend_equals_object(zval *op1, zval *op2, zend_uchar equals); ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 8943929a048bc..b8bb13e8655f1 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -501,7 +501,11 @@ ZEND_VM_HELPER(zend_is_equal_helper, ANY, ANY, zval *op_1, zval *op_2) if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) { op_2 = ZVAL_UNDEFINED_OP2(); } - ret = zend_compare(op_1, op_2); + if (Z_TYPE_P(op_1) == IS_OBJECT || Z_TYPE_P(op_2) == IS_OBJECT) { + ret = zend_equals_object(op_1, op_2, ZEND_IS_EQUAL); + } else { + ret = zend_compare(op_1, op_2); + } if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_nogc(op_1); } @@ -581,7 +585,11 @@ ZEND_VM_HELPER(zend_is_not_equal_helper, ANY, ANY, zval *op_1, zval *op_2) if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) { op_2 = ZVAL_UNDEFINED_OP2(); } - ret = zend_compare(op_1, op_2); + if (Z_TYPE_P(op_1) == IS_OBJECT || Z_TYPE_P(op_2) == IS_OBJECT) { + ret = zend_equals_object(op_1, op_2, ZEND_IS_NOT_EQUAL); + } else { + ret = zend_compare(op_1, op_2); + } if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_nogc(op_1); } @@ -802,7 +810,12 @@ ZEND_VM_HELPER(zend_is_larger_helper, ANY, ANY, zval *op_1, zval *op_2) if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_nogc(op_2); } - ZEND_VM_SMART_BRANCH(ret > 0, 1); + + if (ret > 1) { + ZEND_VM_SMART_BRANCH(false, 1); + } else { + ZEND_VM_SMART_BRANCH(ret > 0, 1); + } } ZEND_VM_HOT_NOCONSTCONST_HANDLER(203, ZEND_IS_LARGER, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH)) @@ -867,7 +880,11 @@ ZEND_VM_HELPER(zend_is_larger_or_equal_helper, ANY, ANY, zval *op_1, zval *op_2) if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_nogc(op_2); } - ZEND_VM_SMART_BRANCH(ret >= 0, 1); + if (ret > 1) { + ZEND_VM_SMART_BRANCH(false, 1); + } else { + ZEND_VM_SMART_BRANCH(ret >= 0, 1); + } } ZEND_VM_HOT_NOCONSTCONST_HANDLER(204, ZEND_IS_LARGER_OR_EQUAL, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH)) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 17748835b3bf8..ea2d8d115956c 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -580,7 +580,11 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_equal_hel if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) { op_2 = ZVAL_UNDEFINED_OP2(); } - ret = zend_compare(op_1, op_2); + if (Z_TYPE_P(op_1) == IS_OBJECT || Z_TYPE_P(op_2) == IS_OBJECT) { + ret = zend_equals_object(op_1, op_2, ZEND_IS_EQUAL); + } else { + ret = zend_compare(op_1, op_2); + } if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_nogc(op_1); } @@ -602,7 +606,11 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_not_equal if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) { op_2 = ZVAL_UNDEFINED_OP2(); } - ret = zend_compare(op_1, op_2); + if (Z_TYPE_P(op_1) == IS_OBJECT || Z_TYPE_P(op_2) == IS_OBJECT) { + ret = zend_equals_object(op_1, op_2, ZEND_IS_NOT_EQUAL); + } else { + ret = zend_compare(op_1, op_2); + } if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_nogc(op_1); } @@ -675,7 +683,12 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_larger_he if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_nogc(op_2); } - ZEND_VM_SMART_BRANCH(ret > 0, 1); + + if (ret > 1) { + ZEND_VM_SMART_BRANCH(false, 1); + } else { + ZEND_VM_SMART_BRANCH(ret > 0, 1); + } } static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_larger_or_equal_helper_SPEC(zval *op_1, zval *op_2 ZEND_OPCODE_HANDLER_ARGS_DC) @@ -697,7 +710,11 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_larger_or if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_nogc(op_2); } - ZEND_VM_SMART_BRANCH(ret >= 0, 1); + if (ret > 1) { + ZEND_VM_SMART_BRANCH(false, 1); + } else { + ZEND_VM_SMART_BRANCH(ret >= 0, 1); + } } static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_bw_or_helper_SPEC(zval *op_1, zval *op_2 ZEND_OPCODE_HANDLER_ARGS_DC) From 80497fc600c27bbde640dbaa8bc92422ddd65401 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Mon, 29 Nov 2021 03:27:45 -0800 Subject: [PATCH 11/36] Updating extensions for changes to objects and ZEND_UNCOMPARABLE --- Zend/zend_operators.c | 17 ++++++++++++++++- ext/date/php_date.c | 6 +++--- ext/gmp/gmp.c | 3 ++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index c72d2f0610b03..27596c5020c44 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1552,7 +1552,22 @@ ZEND_API zend_result ZEND_FASTCALL bitwise_not_function(zval *result, zval *op1) op1 = Z_REFVAL_P(op1); goto try_again; default: - ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BW_NOT); + if (Z_TYPE_P(op1) == IS_OBJECT) { + int objSuccess; + objSuccess = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_BW_NOT, result, op1, NULL); + + if (objSuccess == SUCCESS && !EG(exception)) { + return SUCCESS; + } + + if (EG(exception)) { + if (result != op1) { + ZVAL_UNDEF(result); + } + + return FAILURE; + } + } if (result != op1) { ZVAL_UNDEF(result); diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 86e9a91c11c3b..cf97018e34f91 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -1906,11 +1906,11 @@ static int date_object_compare_timezone(zval *tz1, zval *tz2) /* {{{ */ switch (o1->type) { case TIMELIB_ZONETYPE_OFFSET: - return o1->tzi.utc_offset == o2->tzi.utc_offset ? 0 : 1; + return o1->tzi.utc_offset == o2->tzi.utc_offset ? 0 : ZEND_UNCOMPARABLE; case TIMELIB_ZONETYPE_ABBR: - return strcmp(o1->tzi.z.abbr, o2->tzi.z.abbr) ? 1 : 0; + return strcmp(o1->tzi.z.abbr, o2->tzi.z.abbr) ? ZEND_UNCOMPARABLE : 0; case TIMELIB_ZONETYPE_ID: - return strcmp(o1->tzi.tz->name, o2->tzi.tz->name) ? 1 : 0; + return strcmp(o1->tzi.tz->name, o2->tzi.tz->name) ? ZEND_UNCOMPARABLE : 0; EMPTY_SWITCH_DEFAULT_CASE(); } } /* }}} */ diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index c75e2788b869a..50b7c32eb580a 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -26,6 +26,7 @@ #include "ext/standard/php_var.h" #include "zend_smart_str_public.h" #include "zend_exceptions.h" +#include "zend_operators.h" #include #include "gmp_arginfo.h" @@ -432,7 +433,7 @@ static int gmp_compare(zval *op1, zval *op2) /* {{{ */ /* An error/exception occurs if one of the operands is not a numeric string * or an object which is different from GMP */ if (EG(exception)) { - return 1; + return ZEND_UNCOMPARABLE; } /* result can only be a zend_long if gmp_cmp hasn't thrown an Error */ ZEND_ASSERT(Z_TYPE(result) == IS_LONG); From 3953f376b9c128b053a74905cb579b3db0cd465f Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Mon, 29 Nov 2021 04:09:35 -0800 Subject: [PATCH 12/36] Resolving failing tests for operator overloads --- Zend/tests/operator_unsupported_types.phpt | 4 ++++ Zend/zend_object_handlers.c | 12 ++++++++++-- Zend/zend_operators.c | 16 ++++++++-------- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Zend/tests/operator_unsupported_types.phpt b/Zend/tests/operator_unsupported_types.phpt index c90f0e374ab56..b80c5714ff586 100644 --- a/Zend/tests/operator_unsupported_types.phpt +++ b/Zend/tests/operator_unsupported_types.phpt @@ -3,6 +3,10 @@ Using unsupported types with operators --FILE-- Date: Mon, 29 Nov 2021 08:41:52 -0800 Subject: [PATCH 13/36] Fixing extension handling for object compare handler --- Zend/zend_object_handlers.c | 8 +++++++- ext/gmp/tests/comparison_invalid.phpt | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 13089b52cbd44..74a0dde78ce92 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1794,7 +1794,13 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ continue; } - return zend_std_compare_objects(o1, o2); + if (Z_TYPE_P(o2) == IS_OBJECT && + Z_OBJCE_P(o2)->type == ZEND_INTERNAL_CLASS && + Z_OBJ_HANDLER_P(o2, compare) != zend_std_user_compare_objects) { + return Z_OBJ_HANDLER_P(o2, compare)(o1, o2); + } else { + return zend_std_compare_objects(o1, o2); + } } fci.params = params; diff --git a/ext/gmp/tests/comparison_invalid.phpt b/ext/gmp/tests/comparison_invalid.phpt index edf24e889b8e0..9a8a589e75729 100644 --- a/ext/gmp/tests/comparison_invalid.phpt +++ b/ext/gmp/tests/comparison_invalid.phpt @@ -12,7 +12,7 @@ try { } try { - var_dump((new DateTime()) > gmp_init(0)); + var_dump((new stdClass()) > gmp_init(0)); } catch (\Error $e) { echo $e::class, ': ', $e->getMessage(), \PHP_EOL; } @@ -20,4 +20,4 @@ try { ?> --EXPECT-- ValueError: Number is not an integer string -TypeError: Number must be of type GMP|string|int, DateTime given +TypeError: Number must be of type GMP|string|int, stdClass given From ae584fb0e2e22e2f95562f9de4079fc83dd3da43 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Mon, 29 Nov 2021 08:44:07 -0800 Subject: [PATCH 14/36] Updating pow test --- ext/standard/tests/math/pow_variation1.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/standard/tests/math/pow_variation1.phpt b/ext/standard/tests/math/pow_variation1.phpt index a4283a4ac9464..01bb0e0c35dc2 100644 --- a/ext/standard/tests/math/pow_variation1.phpt +++ b/ext/standard/tests/math/pow_variation1.phpt @@ -159,7 +159,7 @@ Unsupported operand types: string ** int Unsupported operand types: string ** int -- Iteration 23 -- -Unsupported operand types: classA ** int +Operator '**' unsupported by class classA -- Iteration 24 -- int(0) From 0ca2ad087600139be46053e6b53c6094feeb990b Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Mon, 29 Nov 2021 23:40:21 -0800 Subject: [PATCH 15/36] Fixing fallback from __equals to __compareto, and fixing named_params related SIGSEGV --- .../equals_fallback_comparison.phpt | 43 +++++++++++++++++++ Zend/zend_object_handlers.c | 3 +- Zend/zend_operators.c | 12 +++--- 3 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 Zend/tests/operator_overloads/equals_fallback_comparison.phpt diff --git a/Zend/tests/operator_overloads/equals_fallback_comparison.phpt b/Zend/tests/operator_overloads/equals_fallback_comparison.phpt new file mode 100644 index 0000000000000..025cc4105af2b --- /dev/null +++ b/Zend/tests/operator_overloads/equals_fallback_comparison.phpt @@ -0,0 +1,43 @@ +--TEST-- +operator overload: equals fallback to comparison operator +--FILE-- +value <=> $other); + } +} + +$obj = new A(); +$obj->value = 6; + +$bool1 = 12 == $obj; + +var_dump($bool1); + +$bool2 = $obj == 2; + +var_dump($bool2); + +$bool3 = $obj == 6; + +var_dump($bool3); + +$bool4 = $obj == 6.0; + +var_dump($bool4); + +$bool5 = $obj != 6.0; + +var_dump($bool5); +?> +--EXPECT-- +bool(false) +bool(false) +bool(true) +bool(true) +bool(false) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 74a0dde78ce92..f7bced001e9c3 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -250,6 +250,7 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, fci.size = sizeof(fci); fci.retval = result; + fci.named_params = NULL; do { fci.object = zobj; @@ -371,7 +372,6 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, fcic.called_scope = ce; fcic.object = zobj; fcic.function_handler->type = ZEND_USER_FUNCTION; - fci.named_params = NULL; int tmp = zend_call_function(&fci, &fcic); EG(fake_scope) = orig_fake_scope; @@ -1779,6 +1779,7 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ fci.param_count = 1; fci.size = sizeof(fci); fci.retval = &result; + fci.named_params = NULL; do { fci.object = zobj; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 998298aa53673..bf2ece568ba28 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2159,19 +2159,21 @@ ZEND_API int ZEND_FASTCALL zend_equals_object(zval *op1, zval *op2, zend_uchar e } else if (Z_TYPE_P(op1) == IS_OBJECT) { result = Z_OBJ_HANDLER_P(op1, do_operation)(equals, &ret, op1, op2); if (result == FAILURE) { - retVal = zend_compare(op1, op2); + retVal = Z_OBJ_HANDLER_P(op1, compare)(op1, op2); } else { - retVal = (Z_TYPE_INFO(ret) == IS_TRUE ? 0 : 1); + retVal = (Z_TYPE_INFO(ret) == IS_TRUE ? 0 : ZEND_UNCOMPARABLE); } return retVal; - } else { + } else if (Z_TYPE_P(op2) == IS_OBJECT) { result = Z_OBJ_HANDLER_P(op2, do_operation)(equals, &ret, op1, op2); if (result == FAILURE) { - retVal = zend_compare(op1, op2); + retVal = Z_OBJ_HANDLER_P(op2, compare)(op1, op2); } else { - retVal = (Z_TYPE_INFO(ret) == IS_TRUE ? 0 : 1); + retVal = (Z_TYPE_INFO(ret) == IS_TRUE ? 0 : ZEND_UNCOMPARABLE); } return retVal; + } else { + return zend_compare(op1, op2); } } /* }}} */ From ce042d1262d5f3f033e4e311ee9ca785a3a89796 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Tue, 30 Nov 2021 00:12:01 -0800 Subject: [PATCH 16/36] Resolving some build errors in CI --- Zend/zend_object_handlers.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index f7bced001e9c3..7c4be7e8f6a9b 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -252,10 +252,13 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, fci.retval = result; fci.named_params = NULL; + operator = ""; + ZVAL_UNDEF(&left); + do { fci.object = zobj; - Z_TYPE_INFO(left) = is_retry ? IS_FALSE : IS_TRUE; + ZVAL_BOOL(&left, !is_retry); if (is_unary) { fci.param_count = 0; @@ -352,7 +355,7 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, Z_TYPE_INFO(left) = IS_FALSE; is_retry = 1; ZVAL_COPY_VALUE(¶ms[0], op1); - ZVAL_COPY_VALUE(¶ms[1], &left); + ZVAL_BOOL(¶ms[1], i_zend_is_true(&left)); continue; } From 01391839b54afe95032ad522b26174fe85e79d08 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Tue, 30 Nov 2021 00:14:11 -0800 Subject: [PATCH 17/36] Resolving a missed build error in CI --- Zend/zend_object_handlers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 7c4be7e8f6a9b..3b329c1d25d46 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -266,10 +266,10 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, fci.param_count = 2; if (zobj == Z_OBJ_P(op1)) { ZVAL_COPY_VALUE(¶ms[0], op2); - ZVAL_COPY_VALUE(¶ms[1], &left); + ZVAL_BOOL(¶ms[1], i_zend_is_true(&left)); } else { ZVAL_COPY_VALUE(¶ms[0], op1); - ZVAL_COPY_VALUE(¶ms[1], &left); + ZVAL_BOOL(¶ms[1], i_zend_is_true(&left)); } fci.params = params; } From 1e3038f21aa9bd115c67dee129b5ae4af8c9135d Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Tue, 30 Nov 2021 08:44:47 -0800 Subject: [PATCH 18/36] Resolving SIGSEGV --- Zend/zend_API.c | 4 +- Zend/zend_API.h | 14 ++++++ Zend/zend_inheritance.c | 14 ++++++ Zend/zend_object_handlers.c | 28 ++++++++---- ext/opcache/zend_file_cache.c | 28 ++++++++++++ ext/opcache/zend_persist.c | 84 +++++++++++++++++++++++++++++++++++ 6 files changed, 162 insertions(+), 10 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index d6b087f78a5c3..ec13656529cef 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2538,7 +2538,7 @@ static void zend_check_magic_method_unary_operator_overload( zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_OBJECT); } -static void zend_check_magic_method_comparison_operator_overload( +static void zend_check_magic_method_equality_operator_overload( const zend_class_entry *ce, const zend_function *fptr, int error_type) { zend_check_magic_method_args(1, ce, fptr, error_type); @@ -2667,7 +2667,7 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, } else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) { zend_check_magic_method_unary_operator_overload(ce, fptr, error_type); } else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) { - zend_check_magic_method_comparison_operator_overload(ce, fptr, error_type); + zend_check_magic_method_equality_operator_overload(ce, fptr, error_type); } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { zend_check_magic_method_args(1, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); diff --git a/Zend/zend_API.h b/Zend/zend_API.h index a0d5ebee10282..b3647243f7d26 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -283,6 +283,20 @@ typedef struct _zend_fcall_info_cache { class_container.__debugInfo = NULL; \ class_container.__serialize = NULL; \ class_container.__unserialize = NULL; \ + class_container.__add = NULL; \ + class_container.__sub = NULL; \ + class_container.__mul = NULL; \ + class_container.__div = NULL; \ + class_container.__mod = NULL; \ + class_container.__pow = NULL; \ + class_container.__bitwiseand = NULL; \ + class_container.__bitwiseor = NULL; \ + class_container.__bitwisexor = NULL; \ + class_container.__bitwisenot = NULL; \ + class_container.__bitwiseshiftleft = NULL; \ + class_container.__bitwiseshiftright = NULL; \ + class_container.__equals = NULL; \ + class_container.__compareto = NULL; \ class_container.parent = NULL; \ class_container.num_interfaces = 0; \ class_container.trait_names = NULL; \ diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 295e5cf4a47e2..7e585c644470a 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -2638,6 +2638,20 @@ static zend_class_entry *zend_lazy_class_load(zend_class_entry *pce) zend_update_inherited_handler(__debugInfo); zend_update_inherited_handler(__serialize); zend_update_inherited_handler(__unserialize); + zend_update_inherited_handler(__add); + zend_update_inherited_handler(__sub); + zend_update_inherited_handler(__mul); + zend_update_inherited_handler(__div); + zend_update_inherited_handler(__mod); + zend_update_inherited_handler(__pow); + zend_update_inherited_handler(__bitwiseand); + zend_update_inherited_handler(__bitwiseor); + zend_update_inherited_handler(__bitwisexor); + zend_update_inherited_handler(__bitwisenot); + zend_update_inherited_handler(__bitwiseshiftleft); + zend_update_inherited_handler(__bitwiseshiftright); + zend_update_inherited_handler(__equals); + zend_update_inherited_handler(__compareto); } } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 3b329c1d25d46..bd84e4cc5de4a 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -242,15 +242,17 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, zend_class_entry *orig_fake_scope = EG(fake_scope); EG(fake_scope) = NULL; - zend_fcall_info fci; - zend_fcall_info_cache fcic; - zval params[2]; zval left; + zend_fcall_info fci; + zend_fcall_info_cache fcic; + + /* fci setup */ fci.size = sizeof(fci); fci.retval = result; fci.named_params = NULL; + ZVAL_UNDEF(&fci.function_name); /* Unused */ operator = ""; ZVAL_UNDEF(&left); @@ -265,10 +267,10 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, } else { fci.param_count = 2; if (zobj == Z_OBJ_P(op1)) { - ZVAL_COPY_VALUE(¶ms[0], op2); + params[0] = *op2; ZVAL_BOOL(¶ms[1], i_zend_is_true(&left)); } else { - ZVAL_COPY_VALUE(¶ms[0], op1); + params[0] = *op1; ZVAL_BOOL(¶ms[1], i_zend_is_true(&left)); } fci.params = params; @@ -359,9 +361,12 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, continue; } + zval_ptr_dtor(&left); + if (opcode == ZEND_IS_EQUAL || opcode == ZEND_IS_NOT_EQUAL) { /* For equality comparisons, return failure for all objects to */ /* allow the normal override of the compare handler in extensions */ + EG(fake_scope) = orig_fake_scope; return FAILURE; } @@ -369,13 +374,17 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, zend_throw_exception_ex(zend_ce_operator_error, 0, "Operator '%s' unsupported by class %s", operator, ZSTR_VAL(ce->name)); } + EG(fake_scope) = orig_fake_scope; + return FAILURE; } fcic.called_scope = ce; fcic.object = zobj; fcic.function_handler->type = ZEND_USER_FUNCTION; - int tmp = zend_call_function(&fci, &fcic); + zend_result tmp = zend_call_function(&fci, &fcic); + + zval_ptr_dtor(&left); EG(fake_scope) = orig_fake_scope; @@ -1777,12 +1786,15 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ int resultLval; zval params[1]; - params[0] = *o2; + ZVAL_UNDEF(¶ms[0]); + + ZVAL_COPY_VALUE(¶ms[0], o2); fci.param_count = 1; fci.size = sizeof(fci); fci.retval = &result; fci.named_params = NULL; + ZVAL_UNDEF(&fci.function_name); /* Unused */ do { fci.object = zobj; @@ -1793,7 +1805,7 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ if(zobj == Z_OBJ_P(o1) && Z_TYPE_P(o2) == IS_OBJECT && !is_retry) { zobj = Z_OBJ_P(o2); ce = Z_OBJCE_P(o2); - params[0] = *o1; + ZVAL_COPY_VALUE(¶ms[0], o1); is_retry = 1; continue; } diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index 578556b8ef395..9b24aadf5986c 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -869,6 +869,20 @@ static void zend_file_cache_serialize_class(zval *zv, SERIALIZE_PTR(ce->__tostring); SERIALIZE_PTR(ce->__callstatic); SERIALIZE_PTR(ce->__debugInfo); + SERIALIZE_PTR(ce->__add); + SERIALIZE_PTR(ce->__sub); + SERIALIZE_PTR(ce->__mul); + SERIALIZE_PTR(ce->__div); + SERIALIZE_PTR(ce->__mod); + SERIALIZE_PTR(ce->__pow); + SERIALIZE_PTR(ce->__bitwiseand); + SERIALIZE_PTR(ce->__bitwiseor); + SERIALIZE_PTR(ce->__bitwisexor); + SERIALIZE_PTR(ce->__bitwisenot); + SERIALIZE_PTR(ce->__bitwiseshiftleft); + SERIALIZE_PTR(ce->__bitwiseshiftright); + SERIALIZE_PTR(ce->__equals); + SERIALIZE_PTR(ce->__compareto); if (ce->iterator_funcs_ptr) { SERIALIZE_PTR(ce->iterator_funcs_ptr->zf_new_iterator); @@ -1660,6 +1674,20 @@ static void zend_file_cache_unserialize_class(zval *zv, UNSERIALIZE_PTR(ce->__tostring); UNSERIALIZE_PTR(ce->__callstatic); UNSERIALIZE_PTR(ce->__debugInfo); + UNSERIALIZE_PTR(ce->__add); + UNSERIALIZE_PTR(ce->__sub); + UNSERIALIZE_PTR(ce->__mul); + UNSERIALIZE_PTR(ce->__div); + UNSERIALIZE_PTR(ce->__mod); + UNSERIALIZE_PTR(ce->__pow); + UNSERIALIZE_PTR(ce->__bitwiseand); + UNSERIALIZE_PTR(ce->__bitwiseor); + UNSERIALIZE_PTR(ce->__bitwisexor); + UNSERIALIZE_PTR(ce->__bitwisenot); + UNSERIALIZE_PTR(ce->__bitwiseshiftleft); + UNSERIALIZE_PTR(ce->__bitwiseshiftright); + UNSERIALIZE_PTR(ce->__equals); + UNSERIALIZE_PTR(ce->__compareto); if (ce->iterator_funcs_ptr) { UNSERIALIZE_PTR(ce->iterator_funcs_ptr); diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index c438e6b38b81c..2ac7781a6834b 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -1216,6 +1216,90 @@ void zend_update_parent_ce(zend_class_entry *ce) ce->__debugInfo = tmp; } } + if (ce->__add) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__add); + if (tmp != NULL) { + ce->__add = tmp; + } + } + if (ce->__sub) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__sub); + if (tmp != NULL) { + ce->__sub = tmp; + } + } + if (ce->__mul) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__mul); + if (tmp != NULL) { + ce->__mul = tmp; + } + } + if (ce->__div) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__div); + if (tmp != NULL) { + ce->__div = tmp; + } + } + if (ce->__mod) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__mod); + if (tmp != NULL) { + ce->__mod = tmp; + } + } + if (ce->__pow) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__pow); + if (tmp != NULL) { + ce->__pow = tmp; + } + } + if (ce->__bitwiseand) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__bitwiseand); + if (tmp != NULL) { + ce->__bitwiseand = tmp; + } + } + if (ce->__bitwiseor) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__bitwiseor); + if (tmp != NULL) { + ce->__bitwiseor = tmp; + } + } + if (ce->__bitwisexor) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__bitwisexor); + if (tmp != NULL) { + ce->__bitwisexor = tmp; + } + } + if (ce->__bitwisenot) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__bitwisenot); + if (tmp != NULL) { + ce->__bitwisenot = tmp; + } + } + if (ce->__bitwiseshiftleft) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__bitwiseshiftleft); + if (tmp != NULL) { + ce->__bitwiseshiftleft = tmp; + } + } + if (ce->__bitwiseshiftright) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__bitwiseshiftright); + if (tmp != NULL) { + ce->__bitwiseshiftright = tmp; + } + } + if (ce->__equals) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__equals); + if (tmp != NULL) { + ce->__equals = tmp; + } + } + if (ce->__compareto) { + zend_function *tmp = zend_shared_alloc_get_xlat_entry(ce->__compareto); + if (tmp != NULL) { + ce->__compareto = tmp; + } + } } static void zend_accel_persist_class_table(HashTable *class_table) From f3a44b8045a848835f0ef84f453d6394a8eff610 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Tue, 30 Nov 2021 10:34:52 -0800 Subject: [PATCH 19/36] removing ZEND_USER_FUNCTION set --- Zend/zend_object_handlers.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index bd84e4cc5de4a..5bae8efd7d56c 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -267,10 +267,10 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, } else { fci.param_count = 2; if (zobj == Z_OBJ_P(op1)) { - params[0] = *op2; + ZVAL_COPY_VALUE(¶ms[0], op2); ZVAL_BOOL(¶ms[1], i_zend_is_true(&left)); } else { - params[0] = *op1; + ZVAL_COPY_VALUE(¶ms[0], op1); ZVAL_BOOL(¶ms[1], i_zend_is_true(&left)); } fci.params = params; @@ -381,10 +381,12 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, fcic.called_scope = ce; fcic.object = zobj; - fcic.function_handler->type = ZEND_USER_FUNCTION; + //fcic.function_handler->type = ZEND_USER_FUNCTION; zend_result tmp = zend_call_function(&fci, &fcic); zval_ptr_dtor(&left); + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); EG(fake_scope) = orig_fake_scope; @@ -1810,6 +1812,9 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ continue; } + zval_ptr_dtor(&result); + zval_ptr_dtor(¶ms[0]); + if (Z_TYPE_P(o2) == IS_OBJECT && Z_OBJCE_P(o2)->type == ZEND_INTERNAL_CLASS && Z_OBJ_HANDLER_P(o2, compare) != zend_std_user_compare_objects) { @@ -1822,9 +1827,10 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ fci.params = params; fcic.called_scope = ce; fcic.object = zobj; - fcic.function_handler->type = ZEND_USER_FUNCTION; + //fcic.function_handler->type = ZEND_USER_FUNCTION; int tmp = zend_call_function(&fci, &fcic); + zval_ptr_dtor(¶ms[0]); EG(fake_scope) = orig_fake_scope; if (tmp == SUCCESS) { @@ -1834,8 +1840,10 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ resultLval = (resultLval < -1 ? -1 : resultLval); /* Reverse for right hand operand */ resultLval = (is_retry ? resultLval*-1 : resultLval); + zval_ptr_dtor(&result); return resultLval; } else { + zval_ptr_dtor(&result); return ZEND_UNCOMPARABLE; } } while(1); From 96d72ce0c0ba4932dd56f6ef4fe432f3330db3e7 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Tue, 30 Nov 2021 11:03:29 -0800 Subject: [PATCH 20/36] Removing test code --- Zend/zend_object_handlers.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 5bae8efd7d56c..61caba27b710d 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -385,8 +385,6 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, zend_result tmp = zend_call_function(&fci, &fcic); zval_ptr_dtor(&left); - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); EG(fake_scope) = orig_fake_scope; @@ -1788,8 +1786,8 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ int resultLval; zval params[1]; - ZVAL_UNDEF(¶ms[0]); + //ZVAL_UNDEF(&result); ZVAL_COPY_VALUE(¶ms[0], o2); fci.param_count = 1; @@ -1812,9 +1810,6 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ continue; } - zval_ptr_dtor(&result); - zval_ptr_dtor(¶ms[0]); - if (Z_TYPE_P(o2) == IS_OBJECT && Z_OBJCE_P(o2)->type == ZEND_INTERNAL_CLASS && Z_OBJ_HANDLER_P(o2, compare) != zend_std_user_compare_objects) { @@ -1830,7 +1825,6 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ //fcic.function_handler->type = ZEND_USER_FUNCTION; int tmp = zend_call_function(&fci, &fcic); - zval_ptr_dtor(¶ms[0]); EG(fake_scope) = orig_fake_scope; if (tmp == SUCCESS) { @@ -1840,10 +1834,8 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ resultLval = (resultLval < -1 ? -1 : resultLval); /* Reverse for right hand operand */ resultLval = (is_retry ? resultLval*-1 : resultLval); - zval_ptr_dtor(&result); return resultLval; } else { - zval_ptr_dtor(&result); return ZEND_UNCOMPARABLE; } } while(1); From cfda296c002d2b7bf66473bd3f701641a064ed7f Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Tue, 30 Nov 2021 14:01:00 -0800 Subject: [PATCH 21/36] Removing old comment --- Zend/zend_object_handlers.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 61caba27b710d..779f6daf792e9 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -381,7 +381,6 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, fcic.called_scope = ce; fcic.object = zobj; - //fcic.function_handler->type = ZEND_USER_FUNCTION; zend_result tmp = zend_call_function(&fci, &fcic); zval_ptr_dtor(&left); @@ -1822,7 +1821,6 @@ ZEND_API int zend_std_user_compare_objects(zval *o1, zval *o2) /* {{{ */ fci.params = params; fcic.called_scope = ce; fcic.object = zobj; - //fcic.function_handler->type = ZEND_USER_FUNCTION; int tmp = zend_call_function(&fci, &fcic); EG(fake_scope) = orig_fake_scope; From b23f4e7d1e1f1beb6a5898fe732c81a9fbec613b Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Thu, 2 Dec 2021 07:07:25 -0800 Subject: [PATCH 22/36] Trying JIT handling --- ext/opcache/jit/zend_jit.c | 20 ++ ext/opcache/jit/zend_jit_arm64.dasc | 320 ++++++++++++++++++++++++++++ ext/opcache/jit/zend_jit_trace.c | 38 ++++ ext/opcache/jit/zend_jit_x86.dasc | 318 +++++++++++++++++++++++++++ 4 files changed, 696 insertions(+) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 90c3f20f2ee88..89deb7b5ad5ac 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -286,6 +286,24 @@ static int zend_jit_is_constant_cmp_long_long(const zend_op *opline, return 1; } return 0; + case ZEND_IS_LARGER: + if (op1_max > op2_min) { + *result = 1; + return 1; + } else if (op1_min <= op2_max) { + *result = 0; + return 1; + } + return 0; + case ZEND_IS_LARGER_OR_EQUAL: + if (op1_max >= op2_min) { + *result = 1; + return 1; + } else if (op1_min < op2_max) { + *result = 0; + return 1; + } + return 0; default: ZEND_UNREACHABLE(); } @@ -3409,6 +3427,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_CASE: { res_addr = RES_REG_ADDR(); if ((opline->result_type & IS_TMP_VAR) diff --git a/ext/opcache/jit/zend_jit_arm64.dasc b/ext/opcache/jit/zend_jit_arm64.dasc index d142af1bd053b..412b028e99641 100644 --- a/ext/opcache/jit/zend_jit_arm64.dasc +++ b/ext/opcache/jit/zend_jit_arm64.dasc @@ -6571,6 +6571,20 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, | cset REG0w, le } break; + case ZEND_IS_LARGER: + if (swap) { + | cset REG0w, lt + } else { + | cset REG0w, gt + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + | cset REG0w, le + } else { + | cset REG0w, ge + } + break; default: ZEND_UNREACHABLE(); } @@ -6634,6 +6648,36 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, } } break; + case ZEND_IS_LARGER: + if (swap) { + if (exit_addr) { + | bge &exit_addr + } else { + | bge => target_label + } + } else { + if (exit_addr) { + | ble &exit_addr + } else { + | ble => target_label + } + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + if (exit_addr) { + | bgt &exit_addr + } else { + | bgt => target_label + } + } else { + if (exit_addr) { + | blt &exit_addr + } else { + | blt => target_label + } + } + break; default: ZEND_UNREACHABLE(); } @@ -6694,6 +6738,36 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, } } break; + case ZEND_IS_LARGER: + if (swap) { + if (exit_addr) { + | blt &exit_addr + } else { + | blt => target_label + } + } else { + if (exit_addr) { + | bgt &exit_addr + } else { + | bgt => target_label + } + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + if (exit_addr) { + | ble &exit_addr + } else { + | ble => target_label + } + } else { + if (exit_addr) { + | bge &exit_addr + } else { + | bge => target_label + } + } + break; default: ZEND_UNREACHABLE(); } @@ -6723,6 +6797,20 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, | bgt => target_label } break; + case ZEND_IS_LARGER: + if (swap) { + | bge => target_label + } else { + | ble => target_label + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + | bgt => target_label + } else { + | blt => target_label + } + break; default: ZEND_UNREACHABLE(); } @@ -6756,6 +6844,20 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, | cset REG0w, le } break; + case ZEND_IS_LARGER: + if (swap) { + | cset REG0w, lt + } else { + | cset REG0w, gt + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + | cset REG0w, le + } else { + | cset REG0w, ge + } + break; default: ZEND_UNREACHABLE(); } @@ -6834,6 +6936,40 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z } } break; + case ZEND_IS_LARGER: + if (swap) { + if (exit_addr) { + | bvs &exit_addr + | bhs &exit_addr + } else { + | bvs => target_label + | bhs => target_label + } + } else { + if (exit_addr) { + | bls &exit_addr + } else { + | bls => target_label + } + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + if (exit_addr) { + | bvs &exit_addr + | bhi &exit_addr + } else { + | bvs => target_label + | bhi => target_label + } + } else { + if (exit_addr) { + | blo &exit_addr + } else { + | blo => target_label + } + } + break; default: ZEND_UNREACHABLE(); } @@ -6905,6 +7041,44 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z |1: } break; + case ZEND_IS_LARGER: + if (swap) { + | bvs >1 // Always False if involving NaN + if (exit_addr) { + | blo &exit_addr + } else { + | blo => target_label + } + |1: + } else { + | bvs >1 + if (exit_addr) { + | bhi &exit_addr + } else { + | bhi => target_label + } + |1: + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + | bvs >1 // Always False if involving NaN + if (exit_addr) { + | bls &exit_addr + } else { + | bls => target_label + } + |1: + } else { + | bvs >1 + if (exit_addr) { + | bhs &exit_addr + } else { + | bhs => target_label + } + |1: + } + break; default: ZEND_UNREACHABLE(); } @@ -6937,6 +7111,22 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z | bhi => target_label } break; + case ZEND_IS_LARGER: + if (swap) { + | bvs => target_label + | bhs => target_label + } else { + | bls => target_label + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + | bvs => target_label + | bhi => target_label + } else { + | blo => target_label + } + break; default: ZEND_UNREACHABLE(); } @@ -6983,6 +7173,30 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE, TMP1w, TMP2 } break; + case ZEND_IS_LARGER: + if (swap) { + | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE, TMP1w, TMP2 + | bvs => target_label + | bhs => target_label + | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE, TMP1w, TMP2 + } else { + | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE, TMP1w, TMP2 + | bls => target_label + | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE, TMP1w, TMP2 + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE, TMP1w, TMP2 + | bvs => target_label + | bhi => target_label + | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE, TMP1w, TMP2 + } else { + | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE, TMP1w, TMP2 + | blo => target_label + | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE, TMP1w, TMP2 + } + break; default: ZEND_UNREACHABLE(); } @@ -7037,6 +7251,38 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE, TMP1w, TMP2 } break; + case ZEND_IS_LARGER: + if (swap) { + | cset REG0w, lo + | add REG0w, REG0w, #2 + | SET_ZVAL_TYPE_INFO_FROM_REG res_addr, REG0w, TMP1 + | bvs >1 // Always False if involving NaN + | blo => target_label + |1: + } else { + | bvs >1 + | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE, TMP1w, TMP2 + | bhi => target_label + |1: + | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE, TMP1w, TMP2 + } + break; + case ZEND_IS_SMALLER_OR_EQUAL: + if (swap) { + | cset REG0w, ls + | add REG0w, REG0w, #2 + | SET_ZVAL_TYPE_INFO_FROM_REG res_addr, REG0w, TMP1 + | bvs >1 // Always False if involving NaN + | bls => target_label + |1: + } else { + | bvs >1 + | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE, TMP1w, TMP2 + | bhs => target_label + |1: + | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE, TMP1w, TMP2 + } + break; default: ZEND_UNREACHABLE(); } @@ -7089,6 +7335,30 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z | mov REG0, #IS_FALSE |2: break; + case ZEND_IS_LARGER: + | bvs >1 + | mov REG0, #IS_TRUE + || if (swap) { + | blo >2 + || } else { + | bhi >2 + || } + |1: + | mov REG0, #IS_FALSE + |2: + break; + case ZEND_IS_LARGER_OR_EQUAL: + | bvs >1 + | mov REG0, #IS_TRUE + || if (swap) { + | bls >2 + || } else { + | bhs >2 + || } + |1: + | mov REG0, #IS_FALSE + |2: + break; default: ZEND_UNREACHABLE(); } @@ -7157,6 +7427,12 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a case ZEND_IS_SMALLER_OR_EQUAL: | cset REG0w, le break; + case ZEND_IS_LARGER: + | cset REG0w, gt + break; + case ZEND_IS_LARGER_OR_EQUAL: + | cset REG0w, ge + break; default: ZEND_UNREACHABLE(); } @@ -7195,6 +7471,20 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a | bgt => target_label } break; + case ZEND_IS_LARGER: + if (exit_addr) { + | ble &exit_addr + } else { + | ble => target_label + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (exit_addr) { + | blt &exit_addr + } else { + | blt => target_label + } + break; default: ZEND_UNREACHABLE(); } @@ -7230,6 +7520,20 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a | ble => target_label } break; + case ZEND_IS_LARGER: + if (exit_addr) { + | bgt &exit_addr + } else { + | bgt => target_label + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (exit_addr) { + | bge &exit_addr + } else { + | bge => target_label + } + break; default: ZEND_UNREACHABLE(); } @@ -7248,6 +7552,12 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a case ZEND_IS_SMALLER_OR_EQUAL: | bgt => target_label break; + case ZEND_IS_LARGER: + | ble => target_label + break; + case ZEND_IS_LARGER_OR_EQUAL: + | blt => target_label + break; default: ZEND_UNREACHABLE(); } @@ -7270,6 +7580,12 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a case ZEND_IS_SMALLER_OR_EQUAL: | cset REG0w, le break; + case ZEND_IS_LARGER: + | cset REG0w, gt + break; + case ZEND_IS_LARGER_OR_EQUAL: + | cset REG0w, ge + break; default: ZEND_UNREACHABLE(); } @@ -14924,6 +15240,8 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa case ZEND_QM_ASSIGN: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_IS_EQUAL: case ZEND_IS_NOT_EQUAL: case ZEND_IS_IDENTICAL: @@ -15264,6 +15582,8 @@ static zend_regset zend_jit_get_scratch_regset(const zend_op *opline, const zend break; case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_IS_EQUAL: case ZEND_IS_NOT_EQUAL: case ZEND_IS_IDENTICAL: diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 39770e11fb136..b0adfcd742614 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -280,6 +280,8 @@ static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_CASE: case ZEND_CASE_STRICT: case ZEND_ISSET_ISEMPTY_CV: @@ -1729,6 +1731,8 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_CASE: case ZEND_IS_IDENTICAL: case ZEND_IS_NOT_IDENTICAL: @@ -3751,6 +3755,36 @@ static void zend_jit_trace_update_condition_ranges(const zend_op *opline, const } } break; + case ZEND_IS_LARGER: + /* op1 > op2 */ + if (ssa_op->op1_use >= 0) { + zend_jit_trace_set_var_range( + &ssa->var_info[ssa_op->op1_use], + op2_min != ZEND_LONG_MAX ? MAX(op1_min, op2_min + 1) : op1_min, + op1_max); + } + if (ssa_op->op2_use >= 0) { + zend_jit_trace_set_var_range( + &ssa->var_info[ssa_op->op2_use], + op2_min, + op2_max != ZEND_LONG_MIN ?MIN(op2_max, op1_max - 1) : op1_max); + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + /* op1 >= op2 */ + if (ssa_op->op1_use >= 0) { + zend_jit_trace_set_var_range( + &ssa->var_info[ssa_op->op1_use], + MAX(op1_min, op2_min), + op1_max); + } + if (ssa_op->op2_use >= 0) { + zend_jit_trace_set_var_range( + &ssa->var_info[ssa_op->op2_use], + op2_min, + MIN(op2_max, op1_max)); + } + break; } } @@ -3826,6 +3860,8 @@ static bool zend_jit_may_skip_comparison(const zend_op *opline, const zend_ssa_o || prev_opcode == ZEND_IS_NOT_EQUAL || prev_opcode == ZEND_IS_SMALLER || prev_opcode == ZEND_IS_SMALLER_OR_EQUAL + || prev_opcode == ZEND_IS_LARGER + || prev_opcode == ZEND_IS_LARGER_OR_EQUAL || prev_opcode == ZEND_CASE || prev_opcode == ZEND_IS_IDENTICAL || prev_opcode == ZEND_IS_NOT_IDENTICAL @@ -5098,6 +5134,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par case ZEND_IS_NOT_EQUAL: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_CASE: op1_info = OP1_INFO(); op2_info = OP2_INFO(); diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index ef589c94bf0ec..ebb1693d2e090 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -7092,6 +7092,20 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, | setle al } break; + case ZEND_IS_LARGER: + if (swap) { + | setl al + } else { + | setg al + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + | setle al + } else { + | setge al + } + break; default: ZEND_UNREACHABLE(); } @@ -7156,6 +7170,36 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, } } break; + case ZEND_IS_LARGER: + if (swap) { + if (exit_addr) { + | jge &exit_addr + } else { + | jge => target_label + } + } else { + if (exit_addr) { + | jle &exit_addr + } else { + | jle => target_label + } + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + if (exit_addr) { + | jg &exit_addr + } else { + | jg => target_label + } + } else { + if (exit_addr) { + | jl &exit_addr + } else { + | jl => target_label + } + } + break; default: ZEND_UNREACHABLE(); } @@ -7216,6 +7260,36 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, } } break; + case ZEND_IS_LARGER: + if (swap) { + if (exit_addr) { + | jl &exit_addr + } else { + | jl => target_label + } + } else { + if (exit_addr) { + | jg &exit_addr + } else { + | jg => target_label + } + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + if (exit_addr) { + | jle &exit_addr + } else { + | jle => target_label + } + } else { + if (exit_addr) { + | jge &exit_addr + } else { + | jge => target_label + } + } + break; default: ZEND_UNREACHABLE(); } @@ -7245,6 +7319,20 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, | jg => target_label } break; + case ZEND_IS_LARGER: + if (swap) { + | jge => target_label + } else { + | jle => target_label + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + | jg => target_label + } else { + | jl => target_label + } + break; default: ZEND_UNREACHABLE(); } @@ -7278,6 +7366,20 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, | setle al } break; + case ZEND_IS_LARGER: + if (swap) { + | setl al + } else { + | setg al + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + | setle al + } else { + | setge al + } + break; default: ZEND_UNREACHABLE(); } @@ -7359,6 +7461,40 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z } } break; + case ZEND_IS_LARGER: + if (swap) { + if (exit_addr) { + | jae &exit_addr + | jp &exit_addr + } else { + | jae => target_label + | jp => target_label + } + } else { + if (exit_addr) { + | jbe &exit_addr + } else { + | jbe => target_label + } + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + if (exit_addr) { + | ja &exit_addr + | jp &exit_addr + } else { + | ja => target_label + | jp => target_label + } + } else { + if (exit_addr) { + | jb &exit_addr + } else { + | jb => target_label + } + } + break; default: ZEND_UNREACHABLE(); } @@ -7429,6 +7565,40 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z |1: } break; + case ZEND_IS_LARGER: + if (swap) { + if (exit_addr) { + | jb &exit_addr + } else { + | jb => target_label + } + } else { + | jp >1 + if (exit_addr) { + | ja &exit_addr + } else { + | ja => target_label + } + |1: + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (swap) { + if (exit_addr) { + | jbe &exit_addr + } else { + | jbe => target_label + } + } else { + | jp >1 + if (exit_addr) { + | jae &exit_addr + } else { + | jae => target_label + } + |1: + } + break; default: ZEND_UNREACHABLE(); } @@ -7462,6 +7632,22 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z | jp => target_label } break; + case ZEND_LARGER: + if (!swap) { + | jbe => target_label + } else { + | jae => target_label + | jp => target_label + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (!swap) { + | jb => target_label + } else { + | ja => target_label + | jp => target_label + } + break; default: ZEND_UNREACHABLE(); } @@ -7509,6 +7695,30 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE } break; + case ZEND_IS_LARGER: + if (!swap) { + | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE + | jbe => target_label + | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE + } else { + | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE + | jae => target_label + | jp => target_label + | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (!swap) { + | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE + | jb => target_label + | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE + } else { + | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE + | ja => target_label + | jp => target_label + | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE + } + break; default: ZEND_UNREACHABLE(); } @@ -7561,6 +7771,36 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE } break; + case ZEND_IS_LARGER: + if (!swap) { + | seta al + | movzx eax, al + | lea eax, [eax + 2] + | SET_ZVAL_TYPE_INFO res_addr, eax + | ja => target_label + } else { + | jp >1 + | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE + | jb => target_label + |1: + | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (!swap) { + | setae al + | movzx eax, al + | lea eax, [eax + 2] + | SET_ZVAL_TYPE_INFO res_addr, eax + | jae => target_label + } else { + | jp >1 + | SET_ZVAL_TYPE_INFO res_addr, IS_TRUE + | jbe => target_label + |1: + | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE + } + break; default: ZEND_UNREACHABLE(); } @@ -7617,6 +7857,34 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z |2: } break; + case ZEND_IS_LARGER: + if (!swap) { + | seta al + | movzx eax, al + | add eax, 2 + } else { + | jp >1 + | mov eax, IS_TRUE + | jb >2 + |1: + | mov eax, IS_FALSE + |2: + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (!swap) { + | setae al + | movzx eax, al + | add eax, 2 + } else { + | jp >1 + | mov eax, IS_TRUE + | jbe >2 + |1: + | mov eax, IS_FALSE + |2: + } + break; default: ZEND_UNREACHABLE(); } @@ -7685,6 +7953,12 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a case ZEND_IS_SMALLER_OR_EQUAL: | setle al break; + case ZEND_IS_LARGER: + | setg al + break; + case ZEND_IS_LARGER_OR_EQUAL: + | setge al + break; default: ZEND_UNREACHABLE(); } @@ -7724,6 +7998,20 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a | jg => target_label } break; + case ZEND_IS_LARGER: + if (exit_addr) { + | jle &exit_addr + } else { + | jle => target_label + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (exit_addr) { + | jl &exit_addr + } else { + | jl => target_label + } + break; default: ZEND_UNREACHABLE(); } @@ -7759,6 +8047,20 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a | jle => target_label } break; + case ZEND_IS_LARGER: + if (exit_addr) { + | jg &exit_addr + } else { + | jg => target_label + } + break; + case ZEND_IS_LARGER_OR_EQUAL: + if (exit_addr) { + | jge &exit_addr + } else { + | jge => target_label + } + break; default: ZEND_UNREACHABLE(); } @@ -7777,6 +8079,12 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a case ZEND_IS_SMALLER_OR_EQUAL: | jg => target_label break; + case ZEND_IS_LARGER: + | jle => target_label + break; + case ZEND_IS_LARGER_OR_EQUAL: + | jl => target_label + break; default: ZEND_UNREACHABLE(); } @@ -7799,6 +8107,12 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a case ZEND_IS_SMALLER_OR_EQUAL: | setle al break; + case ZEND_IS_LARGER: + | setg al + break; + case ZEND_IS_LARGER_OR_EQUAL: + | setge al + break; default: ZEND_UNREACHABLE(); } @@ -15783,6 +16097,8 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa case ZEND_QM_ASSIGN: case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_IS_EQUAL: case ZEND_IS_NOT_EQUAL: case ZEND_IS_IDENTICAL: @@ -16190,6 +16506,8 @@ bw_op: break; case ZEND_IS_SMALLER: case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: case ZEND_IS_EQUAL: case ZEND_IS_NOT_EQUAL: case ZEND_IS_IDENTICAL: From 5ebaed40d622fd4bd93d36378bc2ce7c9f72498b Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Thu, 2 Dec 2021 07:18:53 -0800 Subject: [PATCH 23/36] Fixing typo in case --- ext/opcache/jit/zend_jit_x86.dasc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index ebb1693d2e090..939337a8ebb6d 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -7632,7 +7632,7 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z | jp => target_label } break; - case ZEND_LARGER: + case ZEND_IS_LARGER: if (!swap) { | jbe => target_label } else { From b042c7dbb1b158924017aa107f9ef13102a98e5a Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Thu, 2 Dec 2021 07:41:39 -0800 Subject: [PATCH 24/36] Another case typo --- ext/opcache/jit/zend_jit_arm64.dasc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_arm64.dasc b/ext/opcache/jit/zend_jit_arm64.dasc index 412b028e99641..8487284990421 100644 --- a/ext/opcache/jit/zend_jit_arm64.dasc +++ b/ext/opcache/jit/zend_jit_arm64.dasc @@ -7267,7 +7267,7 @@ static int zend_jit_cmp_double_common(dasm_State **Dst, const zend_op *opline, z | SET_ZVAL_TYPE_INFO res_addr, IS_FALSE, TMP1w, TMP2 } break; - case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER_OR_EQUAL: if (swap) { | cset REG0w, ls | add REG0w, REG0w, #2 From 29ddc0d0eb735fc497ad8b2b6f2e98aa90a84a5e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 3 Dec 2021 17:03:46 +0100 Subject: [PATCH 25/36] Use operator keyword instead of magic methods --- .../operator_overloads/add_operator.phpt | 2 +- .../operator_overloads/div_operator.phpt | 2 +- .../equals_fallback_comparison.phpt | 2 +- .../operator_overloads/equals_operator.phpt | 2 +- .../operator_overloads/mod_operator.phpt | 2 +- .../operator_overloads/mul_operator.phpt | 2 +- .../operator_omitted_type.phpt | 4 +- .../operator_overloaded.phpt | 94 +++++++-------- .../operator_unimplemented.phpt | 2 +- .../operator_overloads/pow_operator.phpt | 2 +- .../operator_overloads/sub_operator.phpt | 2 +- Zend/zend_API.c | 112 +++++++++--------- Zend/zend_compile.h | 28 ++--- Zend/zend_language_parser.y | 43 +++++-- Zend/zend_language_scanner.l | 22 ++-- ext/tokenizer/tokenizer_data.c | 2 + 16 files changed, 178 insertions(+), 145 deletions(-) diff --git a/Zend/tests/operator_overloads/add_operator.phpt b/Zend/tests/operator_overloads/add_operator.phpt index deff6df64ee4f..5aa63e524c683 100644 --- a/Zend/tests/operator_overloads/add_operator.phpt +++ b/Zend/tests/operator_overloads/add_operator.phpt @@ -6,7 +6,7 @@ operator overload: add operator with scalars class A { public int $value; - public function __add(int $other, bool $left): A + public operator +(int $other, bool $left): A { $return = new A(); $return->value = $this->value + $other; diff --git a/Zend/tests/operator_overloads/div_operator.phpt b/Zend/tests/operator_overloads/div_operator.phpt index f15fb3e3b5d8b..558dd8a098171 100644 --- a/Zend/tests/operator_overloads/div_operator.phpt +++ b/Zend/tests/operator_overloads/div_operator.phpt @@ -6,7 +6,7 @@ operator overload: div operator with scalars class A { public int $value; - public function __div(int $other, bool $left): A + public operator /(int $other, bool $left): A { $return = new A(); diff --git a/Zend/tests/operator_overloads/equals_fallback_comparison.phpt b/Zend/tests/operator_overloads/equals_fallback_comparison.phpt index 025cc4105af2b..57e196e77a596 100644 --- a/Zend/tests/operator_overloads/equals_fallback_comparison.phpt +++ b/Zend/tests/operator_overloads/equals_fallback_comparison.phpt @@ -6,7 +6,7 @@ operator overload: equals fallback to comparison operator class A { public int $value; - public function __compareto(mixed $other): int + public operator <=>(mixed $other): int { return ($this->value <=> $other); } diff --git a/Zend/tests/operator_overloads/equals_operator.phpt b/Zend/tests/operator_overloads/equals_operator.phpt index ac48c6cc0f1c5..7357b5c0f40d3 100644 --- a/Zend/tests/operator_overloads/equals_operator.phpt +++ b/Zend/tests/operator_overloads/equals_operator.phpt @@ -6,7 +6,7 @@ operator overload: equals operator class A { public int $value; - public function __equals(mixed $other): bool + public operator ==(mixed $other): bool { return ($this->value == $other); } diff --git a/Zend/tests/operator_overloads/mod_operator.phpt b/Zend/tests/operator_overloads/mod_operator.phpt index 41414c090ca21..5f80cc674b929 100644 --- a/Zend/tests/operator_overloads/mod_operator.phpt +++ b/Zend/tests/operator_overloads/mod_operator.phpt @@ -6,7 +6,7 @@ operator overload: mod operator with scalars class A { public int $value; - public function __mod(int $other, bool $left): A + public operator %(int $other, bool $left): A { $return = new A(); diff --git a/Zend/tests/operator_overloads/mul_operator.phpt b/Zend/tests/operator_overloads/mul_operator.phpt index 4eb779a377d9e..07278a88ece42 100644 --- a/Zend/tests/operator_overloads/mul_operator.phpt +++ b/Zend/tests/operator_overloads/mul_operator.phpt @@ -6,7 +6,7 @@ operator overload: mul operator with scalars class A { public int $value; - public function __mul(int $other, bool $left): A + public operator *(int $other, bool $left): A { $return = new A(); $return->value = $this->value * $other; diff --git a/Zend/tests/operator_overloads/operator_omitted_type.phpt b/Zend/tests/operator_overloads/operator_omitted_type.phpt index 30d74baf32ad1..a73395810f721 100644 --- a/Zend/tests/operator_overloads/operator_omitted_type.phpt +++ b/Zend/tests/operator_overloads/operator_omitted_type.phpt @@ -6,7 +6,7 @@ operator overload: no explicit type class A { public int $value; - public function __add($other, bool $left): self + public operator +($other, bool $left): self { $return = new A(); $return->value = $this->value + $other; @@ -16,4 +16,4 @@ class A { } ?> --EXPECTF-- -Fatal error: A::__add(): Parameter #1 ($other) must explicitly define a type in %s on line %d +Fatal error: A::+(): Parameter #1 ($other) must explicitly define a type in %s on line %d diff --git a/Zend/tests/operator_overloads/operator_overloaded.phpt b/Zend/tests/operator_overloads/operator_overloaded.phpt index 01c37f70a858a..e04c50b4886ba 100644 --- a/Zend/tests/operator_overloads/operator_overloaded.phpt +++ b/Zend/tests/operator_overloads/operator_overloaded.phpt @@ -4,64 +4,64 @@ operator overload: overload called >(mixed $other, bool $left): self { - echo "__bitwiseShiftRight() called\n"; + echo ">>() called\n"; return $this; } } @@ -94,26 +94,26 @@ $obj >> 1; ?> --EXPECT-- -__add() called -__add() called -__sub() called -__sub() called -__mul() called -__mul() called -__div() called -__div() called -__mod() called -__mod() called -__pow() called -__pow() called -__bitwiseAnd() called -__bitwiseAnd() called -__bitwiseOr() called -__bitwiseOr() called -__bitwiseXor() called -__bitwiseXor() called -__bitwiseShiftLeft() called -__bitwiseShiftLeft() called -__bitwiseShiftRight() called -__bitwiseShiftRight() called -__bitwiseNot() called ++() called ++() called +-() called +-() called +*() called +*() called +/() called +/() called +%() called +%() called +**() called +**() called +&() called +&() called +|() called +|() called +^() called +^() called +<<() called +<<() called +>>() called +>>() called +~() called diff --git a/Zend/tests/operator_overloads/operator_unimplemented.phpt b/Zend/tests/operator_overloads/operator_unimplemented.phpt index 59f1928d2b1d1..75784449b3c2a 100644 --- a/Zend/tests/operator_overloads/operator_unimplemented.phpt +++ b/Zend/tests/operator_overloads/operator_unimplemented.phpt @@ -10,7 +10,7 @@ class A { class B { public int $value; - public function __add(int|A $other, bool $left): B + public operator +(int|A $other, bool $left): B { $return = new B(); if (is_int($other)) { diff --git a/Zend/tests/operator_overloads/pow_operator.phpt b/Zend/tests/operator_overloads/pow_operator.phpt index 4a7914b2a8be9..a2f56dda411b5 100644 --- a/Zend/tests/operator_overloads/pow_operator.phpt +++ b/Zend/tests/operator_overloads/pow_operator.phpt @@ -6,7 +6,7 @@ operator overload: pow operator with scalars class A { public int $value; - public function __pow(int $other, bool $left): A + public operator **(int $other, bool $left): A { $return = new A(); diff --git a/Zend/tests/operator_overloads/sub_operator.phpt b/Zend/tests/operator_overloads/sub_operator.phpt index 88910f249c4c5..a45c79ca6d32f 100644 --- a/Zend/tests/operator_overloads/sub_operator.phpt +++ b/Zend/tests/operator_overloads/sub_operator.phpt @@ -6,7 +6,7 @@ operator overload: sub operator with scalars class A { public int $value; - public function __sub(int $other, bool $left): A + public operator -(int $other, bool $left): A { $return = new A(); diff --git a/Zend/zend_API.c b/Zend/zend_API.c index ec13656529cef..2a1c3b3f0fff0 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2551,6 +2551,41 @@ static void zend_check_magic_method_equality_operator_overload( ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, zend_string *lcname, int error_type) /* {{{ */ { + if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_SUB_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_MUL_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_DIV_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_MOD_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWAND_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWOR_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWXOR_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWSL_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWSR_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) { + zend_check_magic_method_unary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) { + zend_check_magic_method_equality_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { + zend_check_magic_method_args(1, ce, fptr, error_type); + zend_check_magic_method_non_static(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_explicit_type(0, ce, fptr, error_type); + zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); + zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_LONG); + } + if (ZSTR_VAL(fptr->common.function_name)[0] != '_' || ZSTR_VAL(fptr->common.function_name)[1] != '_') { return; @@ -2642,45 +2677,42 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, zend_check_magic_method_non_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr, error_type); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_VOID); - } else if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } +} +/* }}} */ + +ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, zend_string *lcname) +{ + if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) { + ce->__add = fptr; } else if (zend_string_equals_literal(lcname, ZEND_SUB_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__sub = fptr; } else if (zend_string_equals_literal(lcname, ZEND_MUL_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__mul = fptr; } else if (zend_string_equals_literal(lcname, ZEND_DIV_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__div = fptr; } else if (zend_string_equals_literal(lcname, ZEND_MOD_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__mod = fptr; } else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__pow = fptr; } else if (zend_string_equals_literal(lcname, ZEND_BWAND_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__bitwiseand = fptr; } else if (zend_string_equals_literal(lcname, ZEND_BWOR_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__bitwiseor = fptr; } else if (zend_string_equals_literal(lcname, ZEND_BWXOR_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__bitwisexor = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) { + ce->__bitwisenot = fptr; } else if (zend_string_equals_literal(lcname, ZEND_BWSL_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__bitwiseshiftleft = fptr; } else if (zend_string_equals_literal(lcname, ZEND_BWSR_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); - } else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) { - zend_check_magic_method_unary_operator_overload(ce, fptr, error_type); + ce->__bitwiseshiftright = fptr; } else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) { - zend_check_magic_method_equality_operator_overload(ce, fptr, error_type); + ce->__equals = fptr; } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { - zend_check_magic_method_args(1, ce, fptr, error_type); - zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); - zend_check_magic_method_explicit_type(0, ce, fptr, error_type); - zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); - zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_LONG); + ce->__compareto = fptr; } -} -/* }}} */ - -ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, zend_string *lcname) -{ + if (ZSTR_VAL(lcname)[0] != '_' || ZSTR_VAL(lcname)[1] != '_') { /* pass */ } else if (zend_string_equals_literal(lcname, ZEND_CLONE_FUNC_NAME)) { @@ -2714,34 +2746,6 @@ ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, z ce->__serialize = fptr; } else if (zend_string_equals_literal(lcname, "__unserialize")) { ce->__unserialize = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) { - ce->__add = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_SUB_FUNC_NAME)) { - ce->__sub = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_MUL_FUNC_NAME)) { - ce->__mul = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_DIV_FUNC_NAME)) { - ce->__div = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_MOD_FUNC_NAME)) { - ce->__mod = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) { - ce->__pow = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_BWAND_FUNC_NAME)) { - ce->__bitwiseand = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_BWOR_FUNC_NAME)) { - ce->__bitwiseor = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_BWXOR_FUNC_NAME)) { - ce->__bitwisexor = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) { - ce->__bitwisenot = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_BWSL_FUNC_NAME)) { - ce->__bitwiseshiftleft = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_BWSR_FUNC_NAME)) { - ce->__bitwiseshiftright = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) { - ce->__equals = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { - ce->__compareto = fptr; } } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index aab5d63bd528b..f13a81e6a1054 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1108,22 +1108,22 @@ END_EXTERN_C() /* operator overload functions */ /* binary operators */ -#define ZEND_ADD_FUNC_NAME "__add" -#define ZEND_SUB_FUNC_NAME "__sub" -#define ZEND_MUL_FUNC_NAME "__mul" -#define ZEND_DIV_FUNC_NAME "__div" -#define ZEND_MOD_FUNC_NAME "__mod" -#define ZEND_POW_FUNC_NAME "__pow" -#define ZEND_BWAND_FUNC_NAME "__bitwiseand" -#define ZEND_BWOR_FUNC_NAME "__bitwiseor" -#define ZEND_BWXOR_FUNC_NAME "__bitwisexor" -#define ZEND_BWSL_FUNC_NAME "__bitwiseshiftleft" -#define ZEND_BWSR_FUNC_NAME "__bitwiseshiftright" +#define ZEND_ADD_FUNC_NAME "+" +#define ZEND_SUB_FUNC_NAME "-" +#define ZEND_MUL_FUNC_NAME "*" +#define ZEND_DIV_FUNC_NAME "/" +#define ZEND_MOD_FUNC_NAME "%" +#define ZEND_POW_FUNC_NAME "**" +#define ZEND_BWAND_FUNC_NAME "&" +#define ZEND_BWOR_FUNC_NAME "|" +#define ZEND_BWXOR_FUNC_NAME "^" +#define ZEND_BWSL_FUNC_NAME "<<" +#define ZEND_BWSR_FUNC_NAME ">>" /* unary operators */ -#define ZEND_BWNOT_FUNC_NAME "__bitwisenot" +#define ZEND_BWNOT_FUNC_NAME "~" /* comparison operators */ -#define ZEND_EQ_FUNC_NAME "__equals" -#define ZEND_COMPARE_FUNC_NAME "__compareto" +#define ZEND_EQ_FUNC_NAME "==" +#define ZEND_COMPARE_FUNC_NAME "<=>" /* The following constants may be combined in CG(compiler_options) * to change the default compiler behavior */ diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 65280f3143808..6fd80dd4b0ccc 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -137,6 +137,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_BREAK "'break'" %token T_CONTINUE "'continue'" %token T_GOTO "'goto'" +%token T_OPERATOR "'operator'" %token T_FUNCTION "'function'" %token T_FN "'fn'" %token T_CONST "'const'" @@ -178,6 +179,14 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_METHOD_C "'__METHOD__'" %token T_FUNC_C "'__FUNCTION__'" %token T_NS_C "'__NAMESPACE__'" +%token '+' "'+'" +%token '-' "'-'" +%token '*' "'*'" +%token '/' "'/'" +%token '%' "'%'" +%token '|' "'|'" +%token '^' "'^'" +%token '~' "'~'" %token END 0 "end of file" %token T_ATTRIBUTE "'#['" @@ -195,15 +204,15 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_COALESCE_EQUAL "'??='" %token T_BOOLEAN_OR "'||'" %token T_BOOLEAN_AND "'&&'" -%token T_IS_EQUAL "'=='" +%token T_IS_EQUAL "'=='" %token T_IS_NOT_EQUAL "'!='" %token T_IS_IDENTICAL "'==='" %token T_IS_NOT_IDENTICAL "'!=='" %token T_IS_SMALLER_OR_EQUAL "'<='" %token T_IS_GREATER_OR_EQUAL "'>='" -%token T_SPACESHIP "'<=>'" -%token T_SL "'<<'" -%token T_SR "'>>'" +%token T_SPACESHIP "'<=>'" +%token T_SL "'<<'" +%token T_SR "'>>'" %token T_INC "'++'" %token T_DEC "'--'" %token T_INT_CAST "'(int)'" @@ -230,15 +239,15 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_NS_SEPARATOR "'\\'" %token T_ELLIPSIS "'...'" %token T_COALESCE "'??'" -%token T_POW "'**'" +%token T_POW "'**'" %token T_POW_EQUAL "'**='" /* We need to split the & token in two to avoid a shift/reduce conflict. For T1&$v and T1&T2, * with only one token lookahead, bison does not know whether to reduce T1 as a complete type, * or shift to continue parsing an intersection type. */ -%token T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG "'&'" +%token T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG "'&'" /* Bison warns on duplicate token literals, so use a different dummy value here. * It will be fixed up by zend_yytnamerr() later. */ -%token T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG "amp" +%token T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG "amp" %token T_BAD_CHARACTER "invalid character" /* Token used to force a parse error from the lexer */ @@ -279,7 +288,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type match match_arm_list non_empty_match_arm_list match_arm match_arm_cond_list %type enum_declaration_statement enum_backing_type enum_case enum_case_expr -%type returns_ref function fn is_reference is_variadic variable_modifiers +%type returns_ref operator function fn is_reference is_variadic variable_modifiers %type method_modifiers non_empty_member_modifiers member_modifier %type optional_property_modifiers property_modifier %type class_modifiers class_modifier use_type backup_fn_flags @@ -287,7 +296,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type backup_lex_pos %type backup_doc_comment -%type reserved_non_modifiers semi_reserved +%type reserved_non_modifiers semi_reserved ampersand overloadable_operator_list %% /* Rules */ @@ -302,7 +311,7 @@ reserved_non_modifiers: | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT | T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS - | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_FN | T_MATCH | T_ENUM + | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_FN | T_MATCH | T_ENUM | T_OPERATOR ; semi_reserved: @@ -310,6 +319,10 @@ semi_reserved: | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC | T_READONLY ; +overloadable_operator_list: + '+' | '-' | '*' | '/' | '%' | ampersand | '|' | '^' | '~' | T_SL | T_SR | T_POW | T_IS_EQUAL | T_SPACESHIP +; + ampersand: T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG | T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG @@ -917,6 +930,12 @@ attributed_class_statement: return_type backup_fn_flags method_body backup_fn_flags { $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $12, $2, $5, zend_ast_get_str($4), $7, NULL, $11, $9, NULL); CG(extra_fn_flags) = $10; } + | method_modifiers operator overloadable_operator_list backup_doc_comment '(' parameter_list ')' + return_type backup_fn_flags method_body backup_fn_flags + { zval zv; + if (zend_lex_tstring(&zv, $3) == FAILURE) { YYABORT; } + $$ = zend_ast_create_decl(ZEND_AST_METHOD, $1 | $11, $2, $4, Z_STR(zv), $6, NULL, $10, $8, NULL); + CG(extra_fn_flags) = $9; } | enum_case { $$ = $1; } ; @@ -1223,6 +1242,10 @@ function: T_FUNCTION { $$ = CG(zend_lineno); } ; +operator: + T_OPERATOR { $$ = CG(zend_lineno); } +; + backup_doc_comment: %empty { $$ = CG(doc_comment); CG(doc_comment) = NULL; } ; diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index a367c2acb82da..ad03d06179d97 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -299,7 +299,7 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state) ZEND_API zend_result zend_lex_tstring(zval *zv, unsigned char *ident) { unsigned char *end = ident; - while ((*end >= 'a' && *end <= 'z') || (*end >= 'A' && *end <= 'Z') || *end == '_') { + while ((*end >= 'a' && *end <= 'z') || (*end >= 'A' && *end <= 'Z') || *end == '_' || *end == '<' || *end == '*' || *end == '+' || *end == '|' || *end == '&' || *end == '^' || *end == '>' || *end == '/' || *end == '-' || *end == '%' || *end == '=' || *end == '~') { end++; } @@ -1388,6 +1388,10 @@ NEWLINE ("\r"|"\n"|"\r\n") RETURN_TOKEN_WITH_IDENT(T_FUNCTION); } +"operator" { + RETURN_TOKEN_WITH_IDENT(T_OPERATOR); +} + "const" { RETURN_TOKEN_WITH_IDENT(T_CONST); } @@ -1772,7 +1776,7 @@ NEWLINE ("\r"|"\n"|"\r\n") } "==" { - RETURN_TOKEN(T_IS_EQUAL); + RETURN_TOKEN_WITH_IDENT(T_IS_EQUAL); } "!="|"<>" { @@ -1780,7 +1784,7 @@ NEWLINE ("\r"|"\n"|"\r\n") } "<=>" { - RETURN_TOKEN(T_SPACESHIP); + RETURN_TOKEN_WITH_IDENT(T_SPACESHIP); } "<=" { @@ -1804,7 +1808,7 @@ NEWLINE ("\r"|"\n"|"\r\n") } "*\*" { - RETURN_TOKEN(T_POW); + RETURN_TOKEN_WITH_IDENT(T_POW); } "*\*=" { @@ -1868,20 +1872,20 @@ NEWLINE ("\r"|"\n"|"\r\n") } "<<" { - RETURN_TOKEN(T_SL); + RETURN_TOKEN_WITH_IDENT(T_SL); } ">>" { - RETURN_TOKEN(T_SR); + RETURN_TOKEN_WITH_IDENT(T_SR); } "&"[ \t\r\n]*("$"|"...") { yyless(1); - RETURN_TOKEN(T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG); + RETURN_TOKEN_WITH_IDENT(T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG); } "&" { - RETURN_TOKEN(T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG); + RETURN_TOKEN_WITH_IDENT(T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG); } "]"|")" { @@ -1895,7 +1899,7 @@ NEWLINE ("\r"|"\n"|"\r\n") } {TOKENS} { - RETURN_TOKEN(yytext[0]); + RETURN_TOKEN_WITH_IDENT(yytext[0]); } diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index a5adc67308485..a5604c0d99059 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -75,6 +75,7 @@ void tokenizer_register_constants(INIT_FUNC_ARGS) { REGISTER_LONG_CONSTANT("T_BREAK", T_BREAK, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_CONTINUE", T_CONTINUE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_GOTO", T_GOTO, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_OPERATOR", T_OPERATOR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_FUNCTION", T_FUNCTION, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_FN", T_FN, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_CONST", T_CONST, CONST_CS | CONST_PERSISTENT); @@ -228,6 +229,7 @@ char *get_token_type_name(int token_type) case T_BREAK: return "T_BREAK"; case T_CONTINUE: return "T_CONTINUE"; case T_GOTO: return "T_GOTO"; + case T_OPERATOR: return "T_OPERATOR"; case T_FUNCTION: return "T_FUNCTION"; case T_FN: return "T_FN"; case T_CONST: return "T_CONST"; From 3697f3956ddd8e35bd10ae81e0abf0ce6d479999 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 3 Dec 2021 17:03:46 +0100 Subject: [PATCH 26/36] Use operator keyword instead of magic methods --- .../operator_overloads/add_operator.phpt | 2 +- .../operator_overloads/div_operator.phpt | 2 +- .../equals_fallback_comparison.phpt | 2 +- .../operator_overloads/equals_operator.phpt | 2 +- .../operator_overloads/mod_operator.phpt | 2 +- .../operator_overloads/mul_operator.phpt | 2 +- .../operator_omitted_type.phpt | 4 +- .../operator_overloaded.phpt | 94 +++++++-------- .../operator_unimplemented.phpt | 2 +- .../operator_overloads/pow_operator.phpt | 2 +- .../operator_overloads/sub_operator.phpt | 2 +- Zend/zend_API.c | 112 +++++++++--------- Zend/zend_compile.h | 28 ++--- Zend/zend_language_parser.y | 43 +++++-- Zend/zend_language_scanner.l | 27 +++-- ext/tokenizer/tokenizer_data.c | 2 + 16 files changed, 181 insertions(+), 147 deletions(-) diff --git a/Zend/tests/operator_overloads/add_operator.phpt b/Zend/tests/operator_overloads/add_operator.phpt index deff6df64ee4f..5aa63e524c683 100644 --- a/Zend/tests/operator_overloads/add_operator.phpt +++ b/Zend/tests/operator_overloads/add_operator.phpt @@ -6,7 +6,7 @@ operator overload: add operator with scalars class A { public int $value; - public function __add(int $other, bool $left): A + public operator +(int $other, bool $left): A { $return = new A(); $return->value = $this->value + $other; diff --git a/Zend/tests/operator_overloads/div_operator.phpt b/Zend/tests/operator_overloads/div_operator.phpt index f15fb3e3b5d8b..558dd8a098171 100644 --- a/Zend/tests/operator_overloads/div_operator.phpt +++ b/Zend/tests/operator_overloads/div_operator.phpt @@ -6,7 +6,7 @@ operator overload: div operator with scalars class A { public int $value; - public function __div(int $other, bool $left): A + public operator /(int $other, bool $left): A { $return = new A(); diff --git a/Zend/tests/operator_overloads/equals_fallback_comparison.phpt b/Zend/tests/operator_overloads/equals_fallback_comparison.phpt index 025cc4105af2b..57e196e77a596 100644 --- a/Zend/tests/operator_overloads/equals_fallback_comparison.phpt +++ b/Zend/tests/operator_overloads/equals_fallback_comparison.phpt @@ -6,7 +6,7 @@ operator overload: equals fallback to comparison operator class A { public int $value; - public function __compareto(mixed $other): int + public operator <=>(mixed $other): int { return ($this->value <=> $other); } diff --git a/Zend/tests/operator_overloads/equals_operator.phpt b/Zend/tests/operator_overloads/equals_operator.phpt index ac48c6cc0f1c5..7357b5c0f40d3 100644 --- a/Zend/tests/operator_overloads/equals_operator.phpt +++ b/Zend/tests/operator_overloads/equals_operator.phpt @@ -6,7 +6,7 @@ operator overload: equals operator class A { public int $value; - public function __equals(mixed $other): bool + public operator ==(mixed $other): bool { return ($this->value == $other); } diff --git a/Zend/tests/operator_overloads/mod_operator.phpt b/Zend/tests/operator_overloads/mod_operator.phpt index 41414c090ca21..5f80cc674b929 100644 --- a/Zend/tests/operator_overloads/mod_operator.phpt +++ b/Zend/tests/operator_overloads/mod_operator.phpt @@ -6,7 +6,7 @@ operator overload: mod operator with scalars class A { public int $value; - public function __mod(int $other, bool $left): A + public operator %(int $other, bool $left): A { $return = new A(); diff --git a/Zend/tests/operator_overloads/mul_operator.phpt b/Zend/tests/operator_overloads/mul_operator.phpt index 4eb779a377d9e..07278a88ece42 100644 --- a/Zend/tests/operator_overloads/mul_operator.phpt +++ b/Zend/tests/operator_overloads/mul_operator.phpt @@ -6,7 +6,7 @@ operator overload: mul operator with scalars class A { public int $value; - public function __mul(int $other, bool $left): A + public operator *(int $other, bool $left): A { $return = new A(); $return->value = $this->value * $other; diff --git a/Zend/tests/operator_overloads/operator_omitted_type.phpt b/Zend/tests/operator_overloads/operator_omitted_type.phpt index 30d74baf32ad1..a73395810f721 100644 --- a/Zend/tests/operator_overloads/operator_omitted_type.phpt +++ b/Zend/tests/operator_overloads/operator_omitted_type.phpt @@ -6,7 +6,7 @@ operator overload: no explicit type class A { public int $value; - public function __add($other, bool $left): self + public operator +($other, bool $left): self { $return = new A(); $return->value = $this->value + $other; @@ -16,4 +16,4 @@ class A { } ?> --EXPECTF-- -Fatal error: A::__add(): Parameter #1 ($other) must explicitly define a type in %s on line %d +Fatal error: A::+(): Parameter #1 ($other) must explicitly define a type in %s on line %d diff --git a/Zend/tests/operator_overloads/operator_overloaded.phpt b/Zend/tests/operator_overloads/operator_overloaded.phpt index 01c37f70a858a..e04c50b4886ba 100644 --- a/Zend/tests/operator_overloads/operator_overloaded.phpt +++ b/Zend/tests/operator_overloads/operator_overloaded.phpt @@ -4,64 +4,64 @@ operator overload: overload called >(mixed $other, bool $left): self { - echo "__bitwiseShiftRight() called\n"; + echo ">>() called\n"; return $this; } } @@ -94,26 +94,26 @@ $obj >> 1; ?> --EXPECT-- -__add() called -__add() called -__sub() called -__sub() called -__mul() called -__mul() called -__div() called -__div() called -__mod() called -__mod() called -__pow() called -__pow() called -__bitwiseAnd() called -__bitwiseAnd() called -__bitwiseOr() called -__bitwiseOr() called -__bitwiseXor() called -__bitwiseXor() called -__bitwiseShiftLeft() called -__bitwiseShiftLeft() called -__bitwiseShiftRight() called -__bitwiseShiftRight() called -__bitwiseNot() called ++() called ++() called +-() called +-() called +*() called +*() called +/() called +/() called +%() called +%() called +**() called +**() called +&() called +&() called +|() called +|() called +^() called +^() called +<<() called +<<() called +>>() called +>>() called +~() called diff --git a/Zend/tests/operator_overloads/operator_unimplemented.phpt b/Zend/tests/operator_overloads/operator_unimplemented.phpt index 59f1928d2b1d1..75784449b3c2a 100644 --- a/Zend/tests/operator_overloads/operator_unimplemented.phpt +++ b/Zend/tests/operator_overloads/operator_unimplemented.phpt @@ -10,7 +10,7 @@ class A { class B { public int $value; - public function __add(int|A $other, bool $left): B + public operator +(int|A $other, bool $left): B { $return = new B(); if (is_int($other)) { diff --git a/Zend/tests/operator_overloads/pow_operator.phpt b/Zend/tests/operator_overloads/pow_operator.phpt index 4a7914b2a8be9..a2f56dda411b5 100644 --- a/Zend/tests/operator_overloads/pow_operator.phpt +++ b/Zend/tests/operator_overloads/pow_operator.phpt @@ -6,7 +6,7 @@ operator overload: pow operator with scalars class A { public int $value; - public function __pow(int $other, bool $left): A + public operator **(int $other, bool $left): A { $return = new A(); diff --git a/Zend/tests/operator_overloads/sub_operator.phpt b/Zend/tests/operator_overloads/sub_operator.phpt index 88910f249c4c5..a45c79ca6d32f 100644 --- a/Zend/tests/operator_overloads/sub_operator.phpt +++ b/Zend/tests/operator_overloads/sub_operator.phpt @@ -6,7 +6,7 @@ operator overload: sub operator with scalars class A { public int $value; - public function __sub(int $other, bool $left): A + public operator -(int $other, bool $left): A { $return = new A(); diff --git a/Zend/zend_API.c b/Zend/zend_API.c index ec13656529cef..2a1c3b3f0fff0 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2551,6 +2551,41 @@ static void zend_check_magic_method_equality_operator_overload( ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, zend_string *lcname, int error_type) /* {{{ */ { + if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_SUB_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_MUL_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_DIV_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_MOD_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWAND_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWOR_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWXOR_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWSL_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWSR_FUNC_NAME)) { + zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) { + zend_check_magic_method_unary_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) { + zend_check_magic_method_equality_operator_overload(ce, fptr, error_type); + } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { + zend_check_magic_method_args(1, ce, fptr, error_type); + zend_check_magic_method_non_static(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_explicit_type(0, ce, fptr, error_type); + zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); + zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_LONG); + } + if (ZSTR_VAL(fptr->common.function_name)[0] != '_' || ZSTR_VAL(fptr->common.function_name)[1] != '_') { return; @@ -2642,45 +2677,42 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, zend_check_magic_method_non_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr, error_type); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_VOID); - } else if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + } +} +/* }}} */ + +ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, zend_string *lcname) +{ + if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) { + ce->__add = fptr; } else if (zend_string_equals_literal(lcname, ZEND_SUB_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__sub = fptr; } else if (zend_string_equals_literal(lcname, ZEND_MUL_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__mul = fptr; } else if (zend_string_equals_literal(lcname, ZEND_DIV_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__div = fptr; } else if (zend_string_equals_literal(lcname, ZEND_MOD_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__mod = fptr; } else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__pow = fptr; } else if (zend_string_equals_literal(lcname, ZEND_BWAND_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__bitwiseand = fptr; } else if (zend_string_equals_literal(lcname, ZEND_BWOR_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__bitwiseor = fptr; } else if (zend_string_equals_literal(lcname, ZEND_BWXOR_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__bitwisexor = fptr; + } else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) { + ce->__bitwisenot = fptr; } else if (zend_string_equals_literal(lcname, ZEND_BWSL_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); + ce->__bitwiseshiftleft = fptr; } else if (zend_string_equals_literal(lcname, ZEND_BWSR_FUNC_NAME)) { - zend_check_magic_method_binary_operator_overload(ce, fptr, error_type); - } else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) { - zend_check_magic_method_unary_operator_overload(ce, fptr, error_type); + ce->__bitwiseshiftright = fptr; } else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) { - zend_check_magic_method_equality_operator_overload(ce, fptr, error_type); + ce->__equals = fptr; } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { - zend_check_magic_method_args(1, ce, fptr, error_type); - zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); - zend_check_magic_method_explicit_type(0, ce, fptr, error_type); - zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); - zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_LONG); + ce->__compareto = fptr; } -} -/* }}} */ - -ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, zend_string *lcname) -{ + if (ZSTR_VAL(lcname)[0] != '_' || ZSTR_VAL(lcname)[1] != '_') { /* pass */ } else if (zend_string_equals_literal(lcname, ZEND_CLONE_FUNC_NAME)) { @@ -2714,34 +2746,6 @@ ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, z ce->__serialize = fptr; } else if (zend_string_equals_literal(lcname, "__unserialize")) { ce->__unserialize = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) { - ce->__add = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_SUB_FUNC_NAME)) { - ce->__sub = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_MUL_FUNC_NAME)) { - ce->__mul = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_DIV_FUNC_NAME)) { - ce->__div = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_MOD_FUNC_NAME)) { - ce->__mod = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) { - ce->__pow = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_BWAND_FUNC_NAME)) { - ce->__bitwiseand = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_BWOR_FUNC_NAME)) { - ce->__bitwiseor = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_BWXOR_FUNC_NAME)) { - ce->__bitwisexor = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) { - ce->__bitwisenot = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_BWSL_FUNC_NAME)) { - ce->__bitwiseshiftleft = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_BWSR_FUNC_NAME)) { - ce->__bitwiseshiftright = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) { - ce->__equals = fptr; - } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { - ce->__compareto = fptr; } } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index aab5d63bd528b..f13a81e6a1054 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1108,22 +1108,22 @@ END_EXTERN_C() /* operator overload functions */ /* binary operators */ -#define ZEND_ADD_FUNC_NAME "__add" -#define ZEND_SUB_FUNC_NAME "__sub" -#define ZEND_MUL_FUNC_NAME "__mul" -#define ZEND_DIV_FUNC_NAME "__div" -#define ZEND_MOD_FUNC_NAME "__mod" -#define ZEND_POW_FUNC_NAME "__pow" -#define ZEND_BWAND_FUNC_NAME "__bitwiseand" -#define ZEND_BWOR_FUNC_NAME "__bitwiseor" -#define ZEND_BWXOR_FUNC_NAME "__bitwisexor" -#define ZEND_BWSL_FUNC_NAME "__bitwiseshiftleft" -#define ZEND_BWSR_FUNC_NAME "__bitwiseshiftright" +#define ZEND_ADD_FUNC_NAME "+" +#define ZEND_SUB_FUNC_NAME "-" +#define ZEND_MUL_FUNC_NAME "*" +#define ZEND_DIV_FUNC_NAME "/" +#define ZEND_MOD_FUNC_NAME "%" +#define ZEND_POW_FUNC_NAME "**" +#define ZEND_BWAND_FUNC_NAME "&" +#define ZEND_BWOR_FUNC_NAME "|" +#define ZEND_BWXOR_FUNC_NAME "^" +#define ZEND_BWSL_FUNC_NAME "<<" +#define ZEND_BWSR_FUNC_NAME ">>" /* unary operators */ -#define ZEND_BWNOT_FUNC_NAME "__bitwisenot" +#define ZEND_BWNOT_FUNC_NAME "~" /* comparison operators */ -#define ZEND_EQ_FUNC_NAME "__equals" -#define ZEND_COMPARE_FUNC_NAME "__compareto" +#define ZEND_EQ_FUNC_NAME "==" +#define ZEND_COMPARE_FUNC_NAME "<=>" /* The following constants may be combined in CG(compiler_options) * to change the default compiler behavior */ diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 65280f3143808..6fd80dd4b0ccc 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -137,6 +137,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_BREAK "'break'" %token T_CONTINUE "'continue'" %token T_GOTO "'goto'" +%token T_OPERATOR "'operator'" %token T_FUNCTION "'function'" %token T_FN "'fn'" %token T_CONST "'const'" @@ -178,6 +179,14 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_METHOD_C "'__METHOD__'" %token T_FUNC_C "'__FUNCTION__'" %token T_NS_C "'__NAMESPACE__'" +%token '+' "'+'" +%token '-' "'-'" +%token '*' "'*'" +%token '/' "'/'" +%token '%' "'%'" +%token '|' "'|'" +%token '^' "'^'" +%token '~' "'~'" %token END 0 "end of file" %token T_ATTRIBUTE "'#['" @@ -195,15 +204,15 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_COALESCE_EQUAL "'??='" %token T_BOOLEAN_OR "'||'" %token T_BOOLEAN_AND "'&&'" -%token T_IS_EQUAL "'=='" +%token T_IS_EQUAL "'=='" %token T_IS_NOT_EQUAL "'!='" %token T_IS_IDENTICAL "'==='" %token T_IS_NOT_IDENTICAL "'!=='" %token T_IS_SMALLER_OR_EQUAL "'<='" %token T_IS_GREATER_OR_EQUAL "'>='" -%token T_SPACESHIP "'<=>'" -%token T_SL "'<<'" -%token T_SR "'>>'" +%token T_SPACESHIP "'<=>'" +%token T_SL "'<<'" +%token T_SR "'>>'" %token T_INC "'++'" %token T_DEC "'--'" %token T_INT_CAST "'(int)'" @@ -230,15 +239,15 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_NS_SEPARATOR "'\\'" %token T_ELLIPSIS "'...'" %token T_COALESCE "'??'" -%token T_POW "'**'" +%token T_POW "'**'" %token T_POW_EQUAL "'**='" /* We need to split the & token in two to avoid a shift/reduce conflict. For T1&$v and T1&T2, * with only one token lookahead, bison does not know whether to reduce T1 as a complete type, * or shift to continue parsing an intersection type. */ -%token T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG "'&'" +%token T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG "'&'" /* Bison warns on duplicate token literals, so use a different dummy value here. * It will be fixed up by zend_yytnamerr() later. */ -%token T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG "amp" +%token T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG "amp" %token T_BAD_CHARACTER "invalid character" /* Token used to force a parse error from the lexer */ @@ -279,7 +288,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type match match_arm_list non_empty_match_arm_list match_arm match_arm_cond_list %type enum_declaration_statement enum_backing_type enum_case enum_case_expr -%type returns_ref function fn is_reference is_variadic variable_modifiers +%type returns_ref operator function fn is_reference is_variadic variable_modifiers %type method_modifiers non_empty_member_modifiers member_modifier %type optional_property_modifiers property_modifier %type class_modifiers class_modifier use_type backup_fn_flags @@ -287,7 +296,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type backup_lex_pos %type backup_doc_comment -%type reserved_non_modifiers semi_reserved +%type reserved_non_modifiers semi_reserved ampersand overloadable_operator_list %% /* Rules */ @@ -302,7 +311,7 @@ reserved_non_modifiers: | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT | T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS - | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_FN | T_MATCH | T_ENUM + | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_FN | T_MATCH | T_ENUM | T_OPERATOR ; semi_reserved: @@ -310,6 +319,10 @@ semi_reserved: | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC | T_READONLY ; +overloadable_operator_list: + '+' | '-' | '*' | '/' | '%' | ampersand | '|' | '^' | '~' | T_SL | T_SR | T_POW | T_IS_EQUAL | T_SPACESHIP +; + ampersand: T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG | T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG @@ -917,6 +930,12 @@ attributed_class_statement: return_type backup_fn_flags method_body backup_fn_flags { $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $12, $2, $5, zend_ast_get_str($4), $7, NULL, $11, $9, NULL); CG(extra_fn_flags) = $10; } + | method_modifiers operator overloadable_operator_list backup_doc_comment '(' parameter_list ')' + return_type backup_fn_flags method_body backup_fn_flags + { zval zv; + if (zend_lex_tstring(&zv, $3) == FAILURE) { YYABORT; } + $$ = zend_ast_create_decl(ZEND_AST_METHOD, $1 | $11, $2, $4, Z_STR(zv), $6, NULL, $10, $8, NULL); + CG(extra_fn_flags) = $9; } | enum_case { $$ = $1; } ; @@ -1223,6 +1242,10 @@ function: T_FUNCTION { $$ = CG(zend_lineno); } ; +operator: + T_OPERATOR { $$ = CG(zend_lineno); } +; + backup_doc_comment: %empty { $$ = CG(doc_comment); CG(doc_comment) = NULL; } ; diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index a367c2acb82da..d2b2274e7fabe 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -299,13 +299,14 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state) ZEND_API zend_result zend_lex_tstring(zval *zv, unsigned char *ident) { unsigned char *end = ident; - while ((*end >= 'a' && *end <= 'z') || (*end >= 'A' && *end <= 'Z') || *end == '_') { + while ((*end >= 'a' && *end <= 'z') || (*end >= 'A' && *end <= 'Z') || *end == '_' || *end == '<' || *end == '*' || *end == '+' || *end == '|' || *end == '&' || *end == '^' || *end == '>' || *end == '/' || *end == '-' || *end == '%' || *end == '=' || *end == '~') { end++; } size_t length = end - ident; - if (length == 0) { - ZEND_ASSERT(ident[0] == '<' && ident[1] == '?' && ident[2] == '='); + ZEND_ASSERT(length > 0); + + if (ident[0] == '<' && ident[1] == '?' && ident[2] == '=') { zend_throw_exception(zend_ce_parse_error, "Cannot use \""operator" { + RETURN_TOKEN_WITH_IDENT(T_OPERATOR); +} + "const" { RETURN_TOKEN_WITH_IDENT(T_CONST); } @@ -1772,7 +1777,7 @@ NEWLINE ("\r"|"\n"|"\r\n") } "==" { - RETURN_TOKEN(T_IS_EQUAL); + RETURN_TOKEN_WITH_IDENT(T_IS_EQUAL); } "!="|"<>" { @@ -1780,7 +1785,7 @@ NEWLINE ("\r"|"\n"|"\r\n") } "<=>" { - RETURN_TOKEN(T_SPACESHIP); + RETURN_TOKEN_WITH_IDENT(T_SPACESHIP); } "<=" { @@ -1804,7 +1809,7 @@ NEWLINE ("\r"|"\n"|"\r\n") } "*\*" { - RETURN_TOKEN(T_POW); + RETURN_TOKEN_WITH_IDENT(T_POW); } "*\*=" { @@ -1868,20 +1873,20 @@ NEWLINE ("\r"|"\n"|"\r\n") } "<<" { - RETURN_TOKEN(T_SL); + RETURN_TOKEN_WITH_IDENT(T_SL); } ">>" { - RETURN_TOKEN(T_SR); + RETURN_TOKEN_WITH_IDENT(T_SR); } "&"[ \t\r\n]*("$"|"...") { yyless(1); - RETURN_TOKEN(T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG); + RETURN_TOKEN_WITH_IDENT(T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG); } "&" { - RETURN_TOKEN(T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG); + RETURN_TOKEN_WITH_IDENT(T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG); } "]"|")" { @@ -1895,7 +1900,7 @@ NEWLINE ("\r"|"\n"|"\r\n") } {TOKENS} { - RETURN_TOKEN(yytext[0]); + RETURN_TOKEN_WITH_IDENT(yytext[0]); } diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index a5adc67308485..a5604c0d99059 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -75,6 +75,7 @@ void tokenizer_register_constants(INIT_FUNC_ARGS) { REGISTER_LONG_CONSTANT("T_BREAK", T_BREAK, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_CONTINUE", T_CONTINUE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_GOTO", T_GOTO, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_OPERATOR", T_OPERATOR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_FUNCTION", T_FUNCTION, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_FN", T_FN, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_CONST", T_CONST, CONST_CS | CONST_PERSISTENT); @@ -228,6 +229,7 @@ char *get_token_type_name(int token_type) case T_BREAK: return "T_BREAK"; case T_CONTINUE: return "T_CONTINUE"; case T_GOTO: return "T_GOTO"; + case T_OPERATOR: return "T_OPERATOR"; case T_FUNCTION: return "T_FUNCTION"; case T_FN: return "T_FN"; case T_CONST: return "T_CONST"; From fc3a89c750315314bdbc248379d9cef495130264 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Fri, 3 Dec 2021 18:07:55 -0800 Subject: [PATCH 27/36] Updating InvalidOperatorError name --- Zend/zend_API.c | 34 ++++++++++++++++++++++++---------- Zend/zend_exceptions.c | 2 +- Zend/zend_exceptions_arginfo.h | 6 +++--- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 2a1c3b3f0fff0..714d74a69f473 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2518,12 +2518,29 @@ static void zend_check_magic_method_no_return_type( } } +static void zend_check_operator_overload_flags(const zend_class_entry *ce, const zend_function *fptr, int error_type) +{ + /* + * Doing these separately from the already present flags checks to + * provide more helpful error messages. + */ + + if (fptr->common.fn_flags & ZEND_ACC_STATIC) { + zend_error_noreturn(error_type, "Operator %s::%s() cannot be static", + ZSTR_VAL(ce->name), ZSTR_VAL(fptr->common.function_name)); + } + if (fptr->common.fn_flags & ZEND_ACC_PRIVATE || fptr->common.fn_flags & ZEND_ACC_PROTECTED) { + zend_error_noreturn(error_type, "Operator %s::%s() must have public visibility", + ZSTR_VAL(ce->name), ZSTR_VAL(fptr->common.function_name)); + } +} + static void zend_check_magic_method_binary_operator_overload( const zend_class_entry *ce, const zend_function *fptr, int error_type) { + zend_check_magic_method_args(2, ce, fptr, error_type); - zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_operator_overload_flags(ce, fptr, error_type); zend_check_magic_method_explicit_type(0, ce, fptr, error_type); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); zend_check_magic_method_arg_type(1, ce, fptr, error_type, MAY_BE_BOOL); @@ -2533,8 +2550,7 @@ static void zend_check_magic_method_unary_operator_overload( const zend_class_entry *ce, const zend_function *fptr, int error_type) { zend_check_magic_method_args(0, ce, fptr, error_type); - zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_operator_overload_flags(ce, fptr, error_type); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_OBJECT); } @@ -2542,8 +2558,7 @@ static void zend_check_magic_method_equality_operator_overload( const zend_class_entry *ce, const zend_function *fptr, int error_type) { zend_check_magic_method_args(1, ce, fptr, error_type); - zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_operator_overload_flags(ce, fptr, error_type); zend_check_magic_method_explicit_type(0, ce, fptr, error_type); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_BOOL); @@ -2579,13 +2594,12 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, zend_check_magic_method_equality_operator_overload(ce, fptr, error_type); } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { zend_check_magic_method_args(1, ce, fptr, error_type); - zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_operator_overload_flags(ce, fptr, error_type); zend_check_magic_method_explicit_type(0, ce, fptr, error_type); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_LONG); } - + if (ZSTR_VAL(fptr->common.function_name)[0] != '_' || ZSTR_VAL(fptr->common.function_name)[1] != '_') { return; @@ -2712,7 +2726,7 @@ ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, z } else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) { ce->__compareto = fptr; } - + if (ZSTR_VAL(lcname)[0] != '_' || ZSTR_VAL(lcname)[1] != '_') { /* pass */ } else if (zend_string_equals_literal(lcname, ZEND_CLONE_FUNC_NAME)) { diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 57ec1ad8b87b0..d861d17025ff3 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -781,7 +781,7 @@ void zend_register_default_exception(void) /* {{{ */ zend_ce_unhandled_match_error = register_class_UnhandledMatchError(zend_ce_error); zend_ce_unhandled_match_error->create_object = zend_default_exception_new; - zend_ce_operator_error = register_class_InvalidOperator(zend_ce_error); + zend_ce_operator_error = register_class_InvalidOperator(zend_ce_type_error); zend_ce_operator_error->create_object = zend_default_exception_new; INIT_CLASS_ENTRY(zend_ce_unwind_exit, "UnwindExit", NULL); diff --git a/Zend/zend_exceptions_arginfo.h b/Zend/zend_exceptions_arginfo.h index 010c27b2c8cab..8a2b06aac88b3 100644 --- a/Zend/zend_exceptions_arginfo.h +++ b/Zend/zend_exceptions_arginfo.h @@ -400,12 +400,12 @@ static zend_class_entry *register_class_UnhandledMatchError(zend_class_entry *cl return class_entry; } -static zend_class_entry *register_class_InvalidOperator(zend_class_entry *class_entry_Error) +static zend_class_entry *register_class_InvalidOperator(zend_class_entry *class_entry_TypeError) { zend_class_entry ce, *class_entry; - INIT_CLASS_ENTRY(ce, "InvalidOperator", class_InvalidOperator_methods); - class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); + INIT_CLASS_ENTRY(ce, "InvalidOperatorError", class_InvalidOperator_methods); + class_entry = zend_register_internal_class_ex(&ce, class_entry_TypeError); return class_entry; } From 9afc789c5075723221771348cbed6a5c35830961 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Fri, 3 Dec 2021 21:02:33 -0800 Subject: [PATCH 28/36] Adding more tests for op overloads --- .../operator_flags_abstract.phpt | 28 +++++++++++++++++++ .../operator_flags_private.phpt | 19 +++++++++++++ .../operator_flags_protected.phpt | 19 +++++++++++++ .../operator_flags_static.phpt | 19 +++++++++++++ .../operator_overloaded.phpt | 22 +++++++++++++++ 5 files changed, 107 insertions(+) create mode 100644 Zend/tests/operator_overloads/operator_flags_abstract.phpt create mode 100644 Zend/tests/operator_overloads/operator_flags_private.phpt create mode 100644 Zend/tests/operator_overloads/operator_flags_protected.phpt create mode 100644 Zend/tests/operator_overloads/operator_flags_static.phpt diff --git a/Zend/tests/operator_overloads/operator_flags_abstract.phpt b/Zend/tests/operator_overloads/operator_flags_abstract.phpt new file mode 100644 index 0000000000000..023a8a212b45d --- /dev/null +++ b/Zend/tests/operator_overloads/operator_flags_abstract.phpt @@ -0,0 +1,28 @@ +--TEST-- +operator overload: abstract +--FILE-- +value = $this->value + $other; + + return $return; + } +} + +$obj = new B(); +$obj->value = 5; + +echo ($obj + 2)->value.PHP_EOL; +?> +--EXPECT-- +7 diff --git a/Zend/tests/operator_overloads/operator_flags_private.phpt b/Zend/tests/operator_overloads/operator_flags_private.phpt new file mode 100644 index 0000000000000..1fd18bee6cb0a --- /dev/null +++ b/Zend/tests/operator_overloads/operator_flags_private.phpt @@ -0,0 +1,19 @@ +--TEST-- +operator overload: private visibility +--FILE-- +value = $this->value + $other; + + return $return; + } +} +?> +--EXPECTF-- +Fatal error: Operator %s::%s() must have public visibility in %s on line %d diff --git a/Zend/tests/operator_overloads/operator_flags_protected.phpt b/Zend/tests/operator_overloads/operator_flags_protected.phpt new file mode 100644 index 0000000000000..8fab31b92f576 --- /dev/null +++ b/Zend/tests/operator_overloads/operator_flags_protected.phpt @@ -0,0 +1,19 @@ +--TEST-- +operator overload: protected visibility +--FILE-- +value = $this->value + $other; + + return $return; + } +} +?> +--EXPECTF-- +Fatal error: Operator %s::%s() must have public visibility in %s on line %d diff --git a/Zend/tests/operator_overloads/operator_flags_static.phpt b/Zend/tests/operator_overloads/operator_flags_static.phpt new file mode 100644 index 0000000000000..c1a6443c1b478 --- /dev/null +++ b/Zend/tests/operator_overloads/operator_flags_static.phpt @@ -0,0 +1,19 @@ +--TEST-- +operator overload: static +--FILE-- +value = $this->value + $other; + + return $return; + } +} +?> +--EXPECTF-- +Fatal error: Operator %s::%s() cannot be static in %s on line %d diff --git a/Zend/tests/operator_overloads/operator_overloaded.phpt b/Zend/tests/operator_overloads/operator_overloaded.phpt index e04c50b4886ba..4c3b31f753f56 100644 --- a/Zend/tests/operator_overloads/operator_overloaded.phpt +++ b/Zend/tests/operator_overloads/operator_overloaded.phpt @@ -70,50 +70,72 @@ $obj = new A(); $obj + 1; 1 + $obj; +$obj += 1; $obj - 1; 1 - $obj; +$obj -= 1; $obj * 1; 1 * $obj; +$obj *= 1; $obj / 1; 1 / $obj; +$obj /= 1; $obj % 1; 1 % $obj; +$obj %= 1; $obj ** 1; 1 ** $obj; +$obj **= 1; $obj & 1; 1 & $obj; +$obj &= 1; $obj | 1; 1 | $obj; +$obj |= 1; $obj ^ 1; 1 ^ $obj; +$obj ^= 1; $obj << 1; 1 << $obj; +$obj <<= 1; $obj >> 1; 1 >> $obj; +$obj >>= 1; ~$obj; ?> --EXPECT-- +() called +() called ++() called +-() called -() called -() called *() called *() called +*() called /() called /() called +/() called +%() called %() called %() called **() called **() called +**() called &() called &() called +&() called +|() called |() called |() called ^() called ^() called +^() called <<() called <<() called +<<() called +>>() called >>() called >>() called ~() called From e044f53830a9ded19f7c16a9542521601ac3f331 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Sun, 5 Dec 2021 13:31:19 -0800 Subject: [PATCH 29/36] Resolving more memory leaks and segfaults --- .../operator_overloaded.phpt | 32 ++ .../operator_unimplemented.phpt | 4 +- Zend/zend_vm_def.h | 99 ++++ Zend/zend_vm_execute.h | 530 ++++++++++++++++++ ext/reflection/tests/bug74454.phpt | 2 +- 5 files changed, 664 insertions(+), 3 deletions(-) diff --git a/Zend/tests/operator_overloads/operator_overloaded.phpt b/Zend/tests/operator_overloads/operator_overloaded.phpt index 4c3b31f753f56..199aaec890219 100644 --- a/Zend/tests/operator_overloads/operator_overloaded.phpt +++ b/Zend/tests/operator_overloads/operator_overloaded.phpt @@ -70,36 +70,52 @@ $obj = new A(); $obj + 1; 1 + $obj; +$obj = $obj + 1; $obj += 1; +$obj++; +++$obj; $obj - 1; 1 - $obj; +$obj = $obj - 1; $obj -= 1; +$obj--; +--$obj; $obj * 1; 1 * $obj; +$obj = $obj * 1; $obj *= 1; +-$obj; $obj / 1; 1 / $obj; +$obj = $obj / 1; $obj /= 1; $obj % 1; 1 % $obj; +$obj = $obj % 1; $obj %= 1; $obj ** 1; 1 ** $obj; +$obj = $obj ** 1; $obj **= 1; $obj & 1; 1 & $obj; +$obj = $obj & 1; $obj &= 1; $obj | 1; 1 | $obj; +$obj = $obj | 1; $obj |= 1; $obj ^ 1; 1 ^ $obj; +$obj = $obj ^ 1; $obj ^= 1; $obj << 1; 1 << $obj; +$obj = $obj << 1; $obj <<= 1; $obj >> 1; 1 >> $obj; +$obj = $obj >> 1; $obj >>= 1; ~$obj; @@ -108,33 +124,49 @@ $obj >>= 1; +() called +() called +() called ++() called ++() called ++() called +-() called -() called -() called -() called +-() called +-() called +*() called +*() called *() called *() called *() called /() called /() called /() called +/() called +%() called %() called %() called %() called **() called **() called **() called +**() called +&() called &() called &() called &() called |() called |() called |() called +|() called +^() called ^() called ^() called ^() called <<() called <<() called <<() called +<<() called +>>() called >>() called >>() called >>() called diff --git a/Zend/tests/operator_overloads/operator_unimplemented.phpt b/Zend/tests/operator_overloads/operator_unimplemented.phpt index 75784449b3c2a..e1bc6af6187c0 100644 --- a/Zend/tests/operator_overloads/operator_unimplemented.phpt +++ b/Zend/tests/operator_overloads/operator_unimplemented.phpt @@ -30,13 +30,13 @@ $obj2->value = 2; try { $num1 = $obj1 + 2; -} catch (InvalidOperator) { +} catch (InvalidOperatorError) { echo "OK!".PHP_EOL; } try { $num2 = 2 + $obj1; -} catch (InvalidOperator) { +} catch (InvalidOperatorError) { echo "STILL OK!".PHP_EOL; } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 30a5182a87f3b..1542a32c675be 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1410,6 +1410,89 @@ ZEND_VM_HANDLER(26, ZEND_ASSIGN_OP, VAR|CV, CONST|TMPVAR|CV, OP) ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + + + if (Z_TYPE_P(var_ptr) == IS_OBJECT) { + bool eager_dtor = false; + switch ((size_t)opline->extended_value) { + case ZEND_ADD: + if (Z_OBJCE_P(var_ptr)->__add != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SUB: + if (Z_OBJCE_P(var_ptr)->__sub != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MUL: + if (Z_OBJCE_P(var_ptr)->__mul != NULL) { + eager_dtor = true; + } + break; + + case ZEND_DIV: + if (Z_OBJCE_P(var_ptr)->__div != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MOD: + if (Z_OBJCE_P(var_ptr)->__mod != NULL) { + eager_dtor = true; + } + break; + + case ZEND_POW: + if (Z_OBJCE_P(var_ptr)->__pow != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_AND: + if (Z_OBJCE_P(var_ptr)->__bitwiseand != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_OR: + if (Z_OBJCE_P(var_ptr)->__bitwiseor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_XOR: + if (Z_OBJCE_P(var_ptr)->__bitwisexor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_NOT: + if (Z_OBJCE_P(var_ptr)->__bitwisenot != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SL: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftleft != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SR: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftright != NULL) { + eager_dtor = true; + } + break; + } + + if (eager_dtor) { + zval_ptr_dtor(var_ptr); + } + } + FREE_OP2(); FREE_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -1641,6 +1724,10 @@ ZEND_VM_HELPER(zend_pre_inc_helper, VAR|CV, ANY) ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + if (Z_TYPE_P(var_ptr) == IS_OBJECT && (Z_OBJCE_P(var_ptr))->__add != NULL) { + zval_ptr_dtor(var_ptr); + } + FREE_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -1693,6 +1780,10 @@ ZEND_VM_HELPER(zend_pre_dec_helper, VAR|CV, ANY) ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + if (Z_TYPE_P(var_ptr) == IS_OBJECT && (Z_OBJCE_P(var_ptr))->__sub != NULL) { + zval_ptr_dtor(var_ptr); + } + FREE_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -1743,6 +1834,10 @@ ZEND_VM_HELPER(zend_post_inc_helper, VAR|CV, ANY) increment_function(var_ptr); } while (0); + if (Z_TYPE_P(var_ptr) == IS_OBJECT && (Z_OBJCE_P(var_ptr))->__add != NULL) { + zval_ptr_dtor(var_ptr); + } + FREE_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -1791,6 +1886,10 @@ ZEND_VM_HELPER(zend_post_dec_helper, VAR|CV, ANY) decrement_function(var_ptr); } while (0); + if (Z_TYPE_P(var_ptr) == IS_OBJECT && (Z_OBJCE_P(var_ptr))->__sub != NULL) { + zval_ptr_dtor(var_ptr); + } + FREE_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index dbfc2ce8add4f..1e7d9ac020cf3 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -22619,6 +22619,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_inc_help ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + if (Z_TYPE_P(var_ptr) == IS_OBJECT && (Z_OBJCE_P(var_ptr))->__add != NULL) { + zval_ptr_dtor(var_ptr); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -22689,6 +22693,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_dec_help ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + if (Z_TYPE_P(var_ptr) == IS_OBJECT && (Z_OBJCE_P(var_ptr))->__sub != NULL) { + zval_ptr_dtor(var_ptr); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -22757,6 +22765,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_inc_hel increment_function(var_ptr); } while (0); + if (Z_TYPE_P(var_ptr) == IS_OBJECT && (Z_OBJCE_P(var_ptr))->__add != NULL) { + zval_ptr_dtor(var_ptr); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -22805,6 +22817,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_dec_hel decrement_function(var_ptr); } while (0); + if (Z_TYPE_P(var_ptr) == IS_OBJECT && (Z_OBJCE_P(var_ptr))->__sub != NULL) { + zval_ptr_dtor(var_ptr); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -23962,6 +23978,89 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_VAR_CONST_HANDL ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + + + if (Z_TYPE_P(var_ptr) == IS_OBJECT) { + bool eager_dtor = false; + switch ((size_t)opline->extended_value) { + case ZEND_ADD: + if (Z_OBJCE_P(var_ptr)->__add != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SUB: + if (Z_OBJCE_P(var_ptr)->__sub != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MUL: + if (Z_OBJCE_P(var_ptr)->__mul != NULL) { + eager_dtor = true; + } + break; + + case ZEND_DIV: + if (Z_OBJCE_P(var_ptr)->__div != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MOD: + if (Z_OBJCE_P(var_ptr)->__mod != NULL) { + eager_dtor = true; + } + break; + + case ZEND_POW: + if (Z_OBJCE_P(var_ptr)->__pow != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_AND: + if (Z_OBJCE_P(var_ptr)->__bitwiseand != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_OR: + if (Z_OBJCE_P(var_ptr)->__bitwiseor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_XOR: + if (Z_OBJCE_P(var_ptr)->__bitwisexor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_NOT: + if (Z_OBJCE_P(var_ptr)->__bitwisenot != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SL: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftleft != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SR: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftright != NULL) { + eager_dtor = true; + } + break; + } + + if (eager_dtor) { + zval_ptr_dtor(var_ptr); + } + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -26516,6 +26615,89 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_HAND ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + + + if (Z_TYPE_P(var_ptr) == IS_OBJECT) { + bool eager_dtor = false; + switch ((size_t)opline->extended_value) { + case ZEND_ADD: + if (Z_OBJCE_P(var_ptr)->__add != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SUB: + if (Z_OBJCE_P(var_ptr)->__sub != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MUL: + if (Z_OBJCE_P(var_ptr)->__mul != NULL) { + eager_dtor = true; + } + break; + + case ZEND_DIV: + if (Z_OBJCE_P(var_ptr)->__div != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MOD: + if (Z_OBJCE_P(var_ptr)->__mod != NULL) { + eager_dtor = true; + } + break; + + case ZEND_POW: + if (Z_OBJCE_P(var_ptr)->__pow != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_AND: + if (Z_OBJCE_P(var_ptr)->__bitwiseand != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_OR: + if (Z_OBJCE_P(var_ptr)->__bitwiseor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_XOR: + if (Z_OBJCE_P(var_ptr)->__bitwisexor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_NOT: + if (Z_OBJCE_P(var_ptr)->__bitwisenot != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SL: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftleft != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SR: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftright != NULL) { + eager_dtor = true; + } + break; + } + + if (eager_dtor) { + zval_ptr_dtor(var_ptr); + } + } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -30445,6 +30627,89 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_VAR_CV_HANDLER( ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + + + if (Z_TYPE_P(var_ptr) == IS_OBJECT) { + bool eager_dtor = false; + switch ((size_t)opline->extended_value) { + case ZEND_ADD: + if (Z_OBJCE_P(var_ptr)->__add != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SUB: + if (Z_OBJCE_P(var_ptr)->__sub != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MUL: + if (Z_OBJCE_P(var_ptr)->__mul != NULL) { + eager_dtor = true; + } + break; + + case ZEND_DIV: + if (Z_OBJCE_P(var_ptr)->__div != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MOD: + if (Z_OBJCE_P(var_ptr)->__mod != NULL) { + eager_dtor = true; + } + break; + + case ZEND_POW: + if (Z_OBJCE_P(var_ptr)->__pow != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_AND: + if (Z_OBJCE_P(var_ptr)->__bitwiseand != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_OR: + if (Z_OBJCE_P(var_ptr)->__bitwiseor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_XOR: + if (Z_OBJCE_P(var_ptr)->__bitwisexor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_NOT: + if (Z_OBJCE_P(var_ptr)->__bitwisenot != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SL: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftleft != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SR: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftright != NULL) { + eager_dtor = true; + } + break; + } + + if (eager_dtor) { + zval_ptr_dtor(var_ptr); + } + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -38790,6 +39055,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_inc_help ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + if (Z_TYPE_P(var_ptr) == IS_OBJECT && (Z_OBJCE_P(var_ptr))->__add != NULL) { + zval_ptr_dtor(var_ptr); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -38859,6 +39128,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_dec_help ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + if (Z_TYPE_P(var_ptr) == IS_OBJECT && (Z_OBJCE_P(var_ptr))->__sub != NULL) { + zval_ptr_dtor(var_ptr); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -38926,6 +39199,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_inc_hel increment_function(var_ptr); } while (0); + if (Z_TYPE_P(var_ptr) == IS_OBJECT && (Z_OBJCE_P(var_ptr))->__add != NULL) { + zval_ptr_dtor(var_ptr); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -38973,6 +39250,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_dec_hel decrement_function(var_ptr); } while (0); + if (Z_TYPE_P(var_ptr) == IS_OBJECT && (Z_OBJCE_P(var_ptr))->__sub != NULL) { + zval_ptr_dtor(var_ptr); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -41113,6 +41394,89 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_CV_CONST_HANDLE } + + if (Z_TYPE_P(var_ptr) == IS_OBJECT) { + bool eager_dtor = false; + switch ((size_t)opline->extended_value) { + case ZEND_ADD: + if (Z_OBJCE_P(var_ptr)->__add != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SUB: + if (Z_OBJCE_P(var_ptr)->__sub != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MUL: + if (Z_OBJCE_P(var_ptr)->__mul != NULL) { + eager_dtor = true; + } + break; + + case ZEND_DIV: + if (Z_OBJCE_P(var_ptr)->__div != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MOD: + if (Z_OBJCE_P(var_ptr)->__mod != NULL) { + eager_dtor = true; + } + break; + + case ZEND_POW: + if (Z_OBJCE_P(var_ptr)->__pow != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_AND: + if (Z_OBJCE_P(var_ptr)->__bitwiseand != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_OR: + if (Z_OBJCE_P(var_ptr)->__bitwiseor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_XOR: + if (Z_OBJCE_P(var_ptr)->__bitwisexor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_NOT: + if (Z_OBJCE_P(var_ptr)->__bitwisenot != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SL: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftleft != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SR: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftright != NULL) { + eager_dtor = true; + } + break; + } + + if (eager_dtor) { + zval_ptr_dtor(var_ptr); + } + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -44754,6 +45118,89 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_HANDL ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + + + if (Z_TYPE_P(var_ptr) == IS_OBJECT) { + bool eager_dtor = false; + switch ((size_t)opline->extended_value) { + case ZEND_ADD: + if (Z_OBJCE_P(var_ptr)->__add != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SUB: + if (Z_OBJCE_P(var_ptr)->__sub != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MUL: + if (Z_OBJCE_P(var_ptr)->__mul != NULL) { + eager_dtor = true; + } + break; + + case ZEND_DIV: + if (Z_OBJCE_P(var_ptr)->__div != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MOD: + if (Z_OBJCE_P(var_ptr)->__mod != NULL) { + eager_dtor = true; + } + break; + + case ZEND_POW: + if (Z_OBJCE_P(var_ptr)->__pow != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_AND: + if (Z_OBJCE_P(var_ptr)->__bitwiseand != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_OR: + if (Z_OBJCE_P(var_ptr)->__bitwiseor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_XOR: + if (Z_OBJCE_P(var_ptr)->__bitwisexor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_NOT: + if (Z_OBJCE_P(var_ptr)->__bitwisenot != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SL: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftleft != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SR: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftright != NULL) { + eager_dtor = true; + } + break; + } + + if (eager_dtor) { + zval_ptr_dtor(var_ptr); + } + } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -49801,6 +50248,89 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_CV_CV_HANDLER(Z } + + if (Z_TYPE_P(var_ptr) == IS_OBJECT) { + bool eager_dtor = false; + switch ((size_t)opline->extended_value) { + case ZEND_ADD: + if (Z_OBJCE_P(var_ptr)->__add != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SUB: + if (Z_OBJCE_P(var_ptr)->__sub != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MUL: + if (Z_OBJCE_P(var_ptr)->__mul != NULL) { + eager_dtor = true; + } + break; + + case ZEND_DIV: + if (Z_OBJCE_P(var_ptr)->__div != NULL) { + eager_dtor = true; + } + break; + + case ZEND_MOD: + if (Z_OBJCE_P(var_ptr)->__mod != NULL) { + eager_dtor = true; + } + break; + + case ZEND_POW: + if (Z_OBJCE_P(var_ptr)->__pow != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_AND: + if (Z_OBJCE_P(var_ptr)->__bitwiseand != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_OR: + if (Z_OBJCE_P(var_ptr)->__bitwiseor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_XOR: + if (Z_OBJCE_P(var_ptr)->__bitwisexor != NULL) { + eager_dtor = true; + } + break; + + case ZEND_BW_NOT: + if (Z_OBJCE_P(var_ptr)->__bitwisenot != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SL: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftleft != NULL) { + eager_dtor = true; + } + break; + + case ZEND_SR: + if (Z_OBJCE_P(var_ptr)->__bitwiseshiftright != NULL) { + eager_dtor = true; + } + break; + } + + if (eager_dtor) { + zval_ptr_dtor(var_ptr); + } + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } diff --git a/ext/reflection/tests/bug74454.phpt b/ext/reflection/tests/bug74454.phpt index 2a61ff7cc0b28..8f23a09376cca 100644 --- a/ext/reflection/tests/bug74454.phpt +++ b/ext/reflection/tests/bug74454.phpt @@ -14,4 +14,4 @@ function load_file() { } ?> --EXPECT-- -ParseError: syntax error, unexpected token "if", expecting "function" or "const" +ParseError: syntax error, unexpected token "if", expecting "operator" or "function" or "const" From 3bae6734e0ca0392e0c9ce22b6a1512334aed42a Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Wed, 8 Dec 2021 17:44:25 -0800 Subject: [PATCH 30/36] Switched to OperandPosition enum --- .../operator_overloads/add_operator.phpt | 2 +- .../operator_overloads/div_operator.phpt | 6 +-- .../operator_overloads/mod_operator.phpt | 4 +- .../operator_overloads/mul_operator.phpt | 2 +- .../operator_flags_abstract.phpt | 4 +- .../operator_flags_private.phpt | 2 +- .../operator_flags_protected.phpt | 2 +- .../operator_flags_static.phpt | 2 +- .../operator_omitted_type.phpt | 2 +- .../operator_overloaded.phpt | 22 ++++----- .../operator_overloads/operator_position.phpt | 32 +++++++++++++ .../operator_unimplemented.phpt | 2 +- .../operator_overloads/pow_operator.phpt | 4 +- .../operator_overloads/sub_operator.phpt | 4 +- Zend/zend_API.c | 12 ++++- Zend/zend_attributes.c | 4 +- Zend/zend_attributes.h | 7 +-- Zend/zend_enum.c | 4 ++ Zend/zend_enum.h | 1 + Zend/zend_enum.stub.php | 6 +++ Zend/zend_enum_arginfo.h | 18 ++++++- Zend/zend_object_handlers.c | 48 ++++++++++++++----- 22 files changed, 142 insertions(+), 48 deletions(-) create mode 100644 Zend/tests/operator_overloads/operator_position.phpt diff --git a/Zend/tests/operator_overloads/add_operator.phpt b/Zend/tests/operator_overloads/add_operator.phpt index 5aa63e524c683..aa50c7baea425 100644 --- a/Zend/tests/operator_overloads/add_operator.phpt +++ b/Zend/tests/operator_overloads/add_operator.phpt @@ -6,7 +6,7 @@ operator overload: add operator with scalars class A { public int $value; - public operator +(int $other, bool $left): A + public operator +(int $other, OperandPosition $left): A { $return = new A(); $return->value = $this->value + $other; diff --git a/Zend/tests/operator_overloads/div_operator.phpt b/Zend/tests/operator_overloads/div_operator.phpt index 558dd8a098171..1885905431a11 100644 --- a/Zend/tests/operator_overloads/div_operator.phpt +++ b/Zend/tests/operator_overloads/div_operator.phpt @@ -4,13 +4,13 @@ operator overload: div operator with scalars value = $this->value / $other; } else { $return->value = $other / $this->value; diff --git a/Zend/tests/operator_overloads/mod_operator.phpt b/Zend/tests/operator_overloads/mod_operator.phpt index 5f80cc674b929..cc03a8d4478d8 100644 --- a/Zend/tests/operator_overloads/mod_operator.phpt +++ b/Zend/tests/operator_overloads/mod_operator.phpt @@ -6,11 +6,11 @@ operator overload: mod operator with scalars class A { public int $value; - public operator %(int $other, bool $left): A + public operator %(int $other, OperandPosition $left): A { $return = new A(); - if ($left) { + if ($left == OperandPosition::LeftSide) { $return->value = $this->value % $other; } else { $return->value = $other % $this->value; diff --git a/Zend/tests/operator_overloads/mul_operator.phpt b/Zend/tests/operator_overloads/mul_operator.phpt index 07278a88ece42..a9aea83abc12c 100644 --- a/Zend/tests/operator_overloads/mul_operator.phpt +++ b/Zend/tests/operator_overloads/mul_operator.phpt @@ -6,7 +6,7 @@ operator overload: mul operator with scalars class A { public int $value; - public operator *(int $other, bool $left): A + public operator *(int $other, OperandPosition $left): A { $return = new A(); $return->value = $this->value * $other; diff --git a/Zend/tests/operator_overloads/operator_flags_abstract.phpt b/Zend/tests/operator_overloads/operator_flags_abstract.phpt index 023a8a212b45d..2d6f14f8d96b5 100644 --- a/Zend/tests/operator_overloads/operator_flags_abstract.phpt +++ b/Zend/tests/operator_overloads/operator_flags_abstract.phpt @@ -6,11 +6,11 @@ operator overload: abstract abstract class A { public int $value; - abstract operator +(int $other, bool $left): self; + abstract operator +(int $other, OperandPosition $left): self; } class B extends A { - public operator +(int $other, bool $left): self + public operator +(int $other, OperandPosition $left): self { $return = new B(); $return->value = $this->value + $other; diff --git a/Zend/tests/operator_overloads/operator_flags_private.phpt b/Zend/tests/operator_overloads/operator_flags_private.phpt index 1fd18bee6cb0a..589e02ccc7289 100644 --- a/Zend/tests/operator_overloads/operator_flags_private.phpt +++ b/Zend/tests/operator_overloads/operator_flags_private.phpt @@ -6,7 +6,7 @@ operator overload: private visibility class A { public int $value; - private operator +($other, bool $left): self + private operator +(mixed $other, OperandPosition $left): self { $return = new A(); $return->value = $this->value + $other; diff --git a/Zend/tests/operator_overloads/operator_flags_protected.phpt b/Zend/tests/operator_overloads/operator_flags_protected.phpt index 8fab31b92f576..cd26725209a7d 100644 --- a/Zend/tests/operator_overloads/operator_flags_protected.phpt +++ b/Zend/tests/operator_overloads/operator_flags_protected.phpt @@ -6,7 +6,7 @@ operator overload: protected visibility class A { public int $value; - protected operator +($other, bool $left): self + protected operator +(mixed $other, OperandPosition $left): self { $return = new A(); $return->value = $this->value + $other; diff --git a/Zend/tests/operator_overloads/operator_flags_static.phpt b/Zend/tests/operator_overloads/operator_flags_static.phpt index c1a6443c1b478..a5da8d258fd36 100644 --- a/Zend/tests/operator_overloads/operator_flags_static.phpt +++ b/Zend/tests/operator_overloads/operator_flags_static.phpt @@ -6,7 +6,7 @@ operator overload: static class A { public int $value; - static operator +($other, bool $left): self + static operator +(mixed $other, OperandPosition $left): self { $return = new A(); $return->value = $this->value + $other; diff --git a/Zend/tests/operator_overloads/operator_omitted_type.phpt b/Zend/tests/operator_overloads/operator_omitted_type.phpt index a73395810f721..8a1f81653a795 100644 --- a/Zend/tests/operator_overloads/operator_omitted_type.phpt +++ b/Zend/tests/operator_overloads/operator_omitted_type.phpt @@ -6,7 +6,7 @@ operator overload: no explicit type class A { public int $value; - public operator +($other, bool $left): self + public operator +($other, OperandPosition $left): self { $return = new A(); $return->value = $this->value + $other; diff --git a/Zend/tests/operator_overloads/operator_overloaded.phpt b/Zend/tests/operator_overloads/operator_overloaded.phpt index 199aaec890219..440e49686a8e1 100644 --- a/Zend/tests/operator_overloads/operator_overloaded.phpt +++ b/Zend/tests/operator_overloads/operator_overloaded.phpt @@ -4,47 +4,47 @@ operator overload: overload called >(mixed $other, bool $left): self + public operator >>(mixed $other, OperandPosition $left): self { echo ">>() called\n"; return $this; diff --git a/Zend/tests/operator_overloads/operator_position.phpt b/Zend/tests/operator_overloads/operator_position.phpt new file mode 100644 index 0000000000000..7f342a3e0dee0 --- /dev/null +++ b/Zend/tests/operator_overloads/operator_position.phpt @@ -0,0 +1,32 @@ +--TEST-- +operator overload: overload called +--FILE-- + +--EXPECT-- +Left side +Right side +Left side +Left side diff --git a/Zend/tests/operator_overloads/operator_unimplemented.phpt b/Zend/tests/operator_overloads/operator_unimplemented.phpt index e1bc6af6187c0..3ca767bba5da3 100644 --- a/Zend/tests/operator_overloads/operator_unimplemented.phpt +++ b/Zend/tests/operator_overloads/operator_unimplemented.phpt @@ -10,7 +10,7 @@ class A { class B { public int $value; - public operator +(int|A $other, bool $left): B + public operator +(int|A $other, OperandPosition $left): B { $return = new B(); if (is_int($other)) { diff --git a/Zend/tests/operator_overloads/pow_operator.phpt b/Zend/tests/operator_overloads/pow_operator.phpt index a2f56dda411b5..95331f9d7244d 100644 --- a/Zend/tests/operator_overloads/pow_operator.phpt +++ b/Zend/tests/operator_overloads/pow_operator.phpt @@ -6,11 +6,11 @@ operator overload: pow operator with scalars class A { public int $value; - public operator **(int $other, bool $left): A + public operator **(int $other, OperandPosition $left): A { $return = new A(); - if ($left) { + if ($left == OperandPosition::LeftSide) { $return->value = $this->value ** $other; } else { $return->value = $other ** $this->value; diff --git a/Zend/tests/operator_overloads/sub_operator.phpt b/Zend/tests/operator_overloads/sub_operator.phpt index a45c79ca6d32f..79b944a6f6a2b 100644 --- a/Zend/tests/operator_overloads/sub_operator.phpt +++ b/Zend/tests/operator_overloads/sub_operator.phpt @@ -6,11 +6,11 @@ operator overload: sub operator with scalars class A { public int $value; - public operator -(int $other, bool $left): A + public operator -(int $other, OperandPosition $left): A { $return = new A(); - if ($left) { + if ($left == OperandPosition::LeftSide) { $return->value = $this->value - $other; } else { $return->value = $other - $this->value; diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 714d74a69f473..5ff3f54b23e81 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2542,8 +2542,18 @@ static void zend_check_magic_method_binary_operator_overload( zend_check_magic_method_args(2, ce, fptr, error_type); zend_check_operator_overload_flags(ce, fptr, error_type); zend_check_magic_method_explicit_type(0, ce, fptr, error_type); + zend_check_magic_method_explicit_type(1, ce, fptr, error_type); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY); - zend_check_magic_method_arg_type(1, ce, fptr, error_type, MAY_BE_BOOL); + zend_type *single_type; + ZEND_TYPE_FOREACH(fptr->common.arg_info[1].type, single_type) { + if (!ZEND_TYPE_HAS_NAME(*single_type) + || !zend_string_equals_literal_ci(ZEND_TYPE_NAME(*single_type), "OperandPosition")) { + zend_error(error_type, "%s::%s(): Parameter #%d ($%s) must be of type %s when declared", + ZSTR_VAL(ce->name), ZSTR_VAL(fptr->common.function_name), + 2, ZSTR_VAL(fptr->common.arg_info[1].name), + "OperandPosition"); + } + } ZEND_TYPE_FOREACH_END(); } static void zend_check_magic_method_unary_operator_overload( diff --git a/Zend/zend_attributes.c b/Zend/zend_attributes.c index 9ba27958d77c1..8561a5fc13271 100644 --- a/Zend/zend_attributes.c +++ b/Zend/zend_attributes.c @@ -167,7 +167,8 @@ static const char *target_names[] = { "method", "property", "class constant", - "parameter" + "parameter", + "operator" }; ZEND_API zend_string *zend_get_attribute_target_names(uint32_t flags) @@ -301,6 +302,7 @@ void zend_register_attribute_ce(void) zend_declare_class_constant_long(zend_ce_attribute, ZEND_STRL("TARGET_PROPERTY"), ZEND_ATTRIBUTE_TARGET_PROPERTY); zend_declare_class_constant_long(zend_ce_attribute, ZEND_STRL("TARGET_CLASS_CONSTANT"), ZEND_ATTRIBUTE_TARGET_CLASS_CONST); zend_declare_class_constant_long(zend_ce_attribute, ZEND_STRL("TARGET_PARAMETER"), ZEND_ATTRIBUTE_TARGET_PARAMETER); + zend_declare_class_constant_long(zend_ce_attribute, ZEND_STRL("TARGET_OPERATOR"), ZEND_ATTRIBUTE_TARGET_OPERATOR); zend_declare_class_constant_long(zend_ce_attribute, ZEND_STRL("TARGET_ALL"), ZEND_ATTRIBUTE_TARGET_ALL); zend_declare_class_constant_long(zend_ce_attribute, ZEND_STRL("IS_REPEATABLE"), ZEND_ATTRIBUTE_IS_REPEATABLE); diff --git a/Zend/zend_attributes.h b/Zend/zend_attributes.h index a55dc562450d2..a0bb86fd90d69 100644 --- a/Zend/zend_attributes.h +++ b/Zend/zend_attributes.h @@ -26,9 +26,10 @@ #define ZEND_ATTRIBUTE_TARGET_PROPERTY (1<<3) #define ZEND_ATTRIBUTE_TARGET_CLASS_CONST (1<<4) #define ZEND_ATTRIBUTE_TARGET_PARAMETER (1<<5) -#define ZEND_ATTRIBUTE_TARGET_ALL ((1<<6) - 1) -#define ZEND_ATTRIBUTE_IS_REPEATABLE (1<<6) -#define ZEND_ATTRIBUTE_FLAGS ((1<<7) - 1) +#define ZEND_ATTRIBUTE_TARGET_OPERATOR (1<<6) +#define ZEND_ATTRIBUTE_TARGET_ALL ((1<<7) - 1) +#define ZEND_ATTRIBUTE_IS_REPEATABLE (1<<7) +#define ZEND_ATTRIBUTE_FLAGS ((1<<8) - 1) /* Flags for zend_attribute.flags */ #define ZEND_ATTRIBUTE_PERSISTENT (1<<0) diff --git a/Zend/zend_enum.c b/Zend/zend_enum.c index ab4e6e4e6f938..7514819a6597e 100644 --- a/Zend/zend_enum.c +++ b/Zend/zend_enum.c @@ -19,6 +19,7 @@ #include "zend.h" #include "zend_API.h" #include "zend_compile.h" +#include "zend_enum.h" #include "zend_enum_arginfo.h" #include "zend_interfaces.h" @@ -31,6 +32,7 @@ ZEND_API zend_class_entry *zend_ce_unit_enum; ZEND_API zend_class_entry *zend_ce_backed_enum; +ZEND_API zend_class_entry *zend_ce_operand_position_enum; static zend_object_handlers enum_handlers; @@ -156,6 +158,8 @@ void zend_register_enum_ce(void) zend_ce_backed_enum = register_class_BackedEnum(zend_ce_unit_enum); zend_ce_backed_enum->interface_gets_implemented = zend_implement_backed_enum; + zend_ce_operand_position_enum = register_class_OperandPosition(); + memcpy(&enum_handlers, &std_object_handlers, sizeof(zend_object_handlers)); enum_handlers.clone_obj = NULL; enum_handlers.compare = zend_objects_not_comparable; diff --git a/Zend/zend_enum.h b/Zend/zend_enum.h index 8b0961a610e32..b989ed1d4f17b 100644 --- a/Zend/zend_enum.h +++ b/Zend/zend_enum.h @@ -26,6 +26,7 @@ BEGIN_EXTERN_C() extern ZEND_API zend_class_entry *zend_ce_unit_enum; extern ZEND_API zend_class_entry *zend_ce_backed_enum; +extern ZEND_API zend_class_entry *zend_ce_operand_position_enum; void zend_register_enum_ce(void); void zend_enum_add_interfaces(zend_class_entry *ce); diff --git a/Zend/zend_enum.stub.php b/Zend/zend_enum.stub.php index 727514a7bd4b7..b9fa6ea048d37 100644 --- a/Zend/zend_enum.stub.php +++ b/Zend/zend_enum.stub.php @@ -13,3 +13,9 @@ public static function from(int|string $value): static; public static function tryFrom(int|string $value): ?static; } + +enum OperandPosition +{ + case LeftSide; + case RightSide; +} \ No newline at end of file diff --git a/Zend/zend_enum_arginfo.h b/Zend/zend_enum_arginfo.h index a1b53cfde4f50..227cd707dd594 100644 --- a/Zend/zend_enum_arginfo.h +++ b/Zend/zend_enum_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7092f1d4ba651f077cff37050899f090f00abf22 */ + * Stub hash: c773a3643be9fff0375f3688bfe72697a564d55a */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_UnitEnum_cases, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -27,6 +27,11 @@ static const zend_function_entry class_BackedEnum_methods[] = { ZEND_FE_END }; + +static const zend_function_entry class_OperandPosition_methods[] = { + ZEND_FE_END +}; + static zend_class_entry *register_class_UnitEnum(void) { zend_class_entry ce, *class_entry; @@ -47,3 +52,14 @@ static zend_class_entry *register_class_BackedEnum(zend_class_entry *class_entry return class_entry; } + +static zend_class_entry *register_class_OperandPosition(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("OperandPosition", IS_UNDEF, class_OperandPosition_methods); + + zend_enum_add_case_cstr(class_entry, "LeftSide", NULL); + + zend_enum_add_case_cstr(class_entry, "RightSide", NULL); + + return class_entry; +} diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 67b1358bd3434..82b86e211f51a 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -30,6 +30,7 @@ #include "zend_closures.h" #include "zend_compile.h" #include "zend_hash.h" +#include "zend_enum.h" #define DEBUG_OBJECT_HANDLERS 0 @@ -243,7 +244,7 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, EG(fake_scope) = NULL; zval params[2]; - zval left; + zval op_pos; zend_fcall_info fci; zend_fcall_info_cache fcic; @@ -255,23 +256,35 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, ZVAL_UNDEF(&fci.function_name); /* Unused */ operator = ""; - ZVAL_UNDEF(&left); + ZVAL_UNDEF(&op_pos); + ZVAL_UNDEF(¶ms[0]); + ZVAL_UNDEF(¶ms[1]); + zend_object left_val = *zend_enum_get_case_cstr(zend_ce_operand_position_enum, "LeftSide"); + zend_object right_val = *zend_enum_get_case_cstr(zend_ce_operand_position_enum, "RightSide"); do { fci.object = zobj; - ZVAL_BOOL(&left, !is_retry); - if (is_unary) { fci.param_count = 0; + } else if (opcode == ZEND_IS_EQUAL || opcode == ZEND_IS_NOT_EQUAL) { + fci.param_count = 1; + if (zobj == Z_OBJ_P(op1)) { + ZVAL_COPY(¶ms[0], op2); + } else { + ZVAL_COPY(¶ms[0], op1); + } + fci.params = params; } else { fci.param_count = 2; if (zobj == Z_OBJ_P(op1)) { - ZVAL_COPY_VALUE(¶ms[0], op2); - ZVAL_BOOL(¶ms[1], i_zend_is_true(&left)); + ZVAL_COPY(¶ms[0], op2); + ZVAL_OBJ_COPY(&op_pos, &left_val); + ZVAL_COPY(¶ms[1], &op_pos); } else { - ZVAL_COPY_VALUE(¶ms[0], op1); - ZVAL_BOOL(¶ms[1], i_zend_is_true(&left)); + ZVAL_COPY(¶ms[0], op1); + ZVAL_OBJ_COPY(&op_pos, &right_val); + ZVAL_COPY(¶ms[1], &op_pos); } fci.params = params; } @@ -354,14 +367,17 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, !is_retry ) { zobj = Z_OBJ_P(op2); ce = Z_OBJCE_P(op2); - Z_TYPE_INFO(left) = IS_FALSE; is_retry = 1; - ZVAL_COPY_VALUE(¶ms[0], op1); - ZVAL_BOOL(¶ms[1], i_zend_is_true(&left)); continue; } - zval_ptr_dtor(&left); + zval_ptr_dtor(&op_pos); + if (!is_unary) { + zval_ptr_dtor(¶ms[0]); + if (opcode != ZEND_IS_EQUAL && opcode != ZEND_IS_NOT_EQUAL) { + zval_ptr_dtor(¶ms[1]); + } + } if (opcode == ZEND_IS_EQUAL || opcode == ZEND_IS_NOT_EQUAL) { /* For equality comparisons, return failure for all objects to */ @@ -383,7 +399,13 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, fcic.object = zobj; zend_result tmp = zend_call_function(&fci, &fcic); - zval_ptr_dtor(&left); + zval_ptr_dtor(&op_pos); + if (!is_unary) { + zval_ptr_dtor(¶ms[0]); + if (opcode != ZEND_IS_EQUAL && opcode != ZEND_IS_NOT_EQUAL) { + zval_ptr_dtor(¶ms[1]); + } + } EG(fake_scope) = orig_fake_scope; From 280ad16254a7f3c20f106b87aa5c78dabc94b888 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Wed, 8 Dec 2021 17:59:55 -0800 Subject: [PATCH 31/36] Updates --- Zend/zend_object_handlers.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 82b86e211f51a..60563a1dc7b3a 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -279,12 +279,10 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, fci.param_count = 2; if (zobj == Z_OBJ_P(op1)) { ZVAL_COPY(¶ms[0], op2); - ZVAL_OBJ_COPY(&op_pos, &left_val); - ZVAL_COPY(¶ms[1], &op_pos); + ZVAL_OBJ_COPY(¶ms[1], &left_val); } else { ZVAL_COPY(¶ms[0], op1); - ZVAL_OBJ_COPY(&op_pos, &right_val); - ZVAL_COPY(¶ms[1], &op_pos); + ZVAL_OBJ_COPY(¶ms[1], &right_val); } fci.params = params; } @@ -376,6 +374,8 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, zval_ptr_dtor(¶ms[0]); if (opcode != ZEND_IS_EQUAL && opcode != ZEND_IS_NOT_EQUAL) { zval_ptr_dtor(¶ms[1]); + GC_TRY_DELREF(&left_val); + GC_TRY_DELREF(&right_val); } } @@ -404,6 +404,8 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, zval_ptr_dtor(¶ms[0]); if (opcode != ZEND_IS_EQUAL && opcode != ZEND_IS_NOT_EQUAL) { zval_ptr_dtor(¶ms[1]); + GC_TRY_DELREF(&left_val); + GC_TRY_DELREF(&right_val); } } From 7e1601baa4a420de3d59cc4c23bf14ca2bcb1098 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 10 Dec 2021 11:39:50 +0100 Subject: [PATCH 32/36] Fix enum case usage in zend_std_call_op_override --- .../operator_overloads/div_operator.phpt | 2 +- Zend/zend_object_handlers.c | 34 +++++++------------ 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/Zend/tests/operator_overloads/div_operator.phpt b/Zend/tests/operator_overloads/div_operator.phpt index 1885905431a11..f016b1a9ca59a 100644 --- a/Zend/tests/operator_overloads/div_operator.phpt +++ b/Zend/tests/operator_overloads/div_operator.phpt @@ -4,7 +4,7 @@ operator overload: div operator with scalars 0) { + zval_ptr_dtor(¶ms[0]); + if (fci.param_count > 1) { + zval_ptr_dtor(¶ms[1]); + } + } + if(zobj == Z_OBJ_P(op1) && !is_unary && Z_TYPE_P(op2) == IS_OBJECT && @@ -369,16 +374,6 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, continue; } - zval_ptr_dtor(&op_pos); - if (!is_unary) { - zval_ptr_dtor(¶ms[0]); - if (opcode != ZEND_IS_EQUAL && opcode != ZEND_IS_NOT_EQUAL) { - zval_ptr_dtor(¶ms[1]); - GC_TRY_DELREF(&left_val); - GC_TRY_DELREF(&right_val); - } - } - if (opcode == ZEND_IS_EQUAL || opcode == ZEND_IS_NOT_EQUAL) { /* For equality comparisons, return failure for all objects to */ /* allow the normal override of the compare handler in extensions */ @@ -399,13 +394,10 @@ static int zend_std_call_op_override(zend_uchar opcode, zval *result, zval *op1, fcic.object = zobj; zend_result tmp = zend_call_function(&fci, &fcic); - zval_ptr_dtor(&op_pos); - if (!is_unary) { + if (fci.param_count > 0) { zval_ptr_dtor(¶ms[0]); - if (opcode != ZEND_IS_EQUAL && opcode != ZEND_IS_NOT_EQUAL) { + if (fci.param_count > 1) { zval_ptr_dtor(¶ms[1]); - GC_TRY_DELREF(&left_val); - GC_TRY_DELREF(&right_val); } } From b0492c4eab6ed10dab0ddf752210fd611be24723 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Fri, 10 Dec 2021 14:43:35 -0800 Subject: [PATCH 33/36] Adding helper functions for extensions --- Zend/zend_object_handlers.c | 174 ++++++++++++++++++++++++++++++++++++ Zend/zend_object_handlers.h | 4 + 2 files changed, 178 insertions(+) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index d0fa6299da8a8..fe6075e70a364 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -2000,6 +2000,180 @@ ZEND_API int zend_objects_not_comparable(zval *o1, zval *o2) return ZEND_UNCOMPARABLE; } +ZEND_API int zend_std_has_op_overload(zend_uchar opcode, zval *obj) +{ + if (Z_TYPE_P(obj) != IS_OBJECT) { + return 0; + } + + zend_class_entry *ce = Z_OBJCE_P(obj); + + switch (opcode) { + case ZEND_ADD: + if (ce->__add != NULL) { + return 1; + } + break; + + case ZEND_SUB: + if (ce->__sub != NULL) { + return 1; + } + break; + + case ZEND_MUL: + if (ce->__mul != NULL) { + return 1; + } + break; + + case ZEND_DIV: + if (ce->__div != NULL) { + return 1; + } + break; + + case ZEND_MOD: + if (ce->__mod != NULL) { + return 1; + } + break; + + case ZEND_POW: + if (ce->__pow != NULL) { + return 1; + } + break; + + case ZEND_BW_AND: + if (ce->__bitwiseand != NULL) { + return 1; + } + break; + + case ZEND_BW_OR: + if (ce->__bitwiseor != NULL) { + return 1; + } + break; + + case ZEND_BW_XOR: + if (ce->__bitwisexor != NULL) { + return 1; + } + break; + + case ZEND_BW_NOT: + if (ce->__bitwisenot != NULL) { + return 1; + } + break; + + case ZEND_SL: + if (ce->__bitwiseshiftleft != NULL) { + return 1; + } + break; + + case ZEND_SR: + if (ce->__bitwiseshiftright != NULL) { + return 1; + } + break; + + case ZEND_IS_EQUAL: + case ZEND_IS_NOT_EQUAL: + if (ce->__equals != NULL) { + return 1; + } + break; + + case ZEND_IS_SMALLER: + case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: + case ZEND_SPACESHIP: + if (ce->__compareto != NULL) { + return 1; + } + break; + + default: + return 0; + } + + return 0; +} + +ZEND_API zend_function *zend_std_get_op_overload(zend_uchar opcode, zend_class_entry *ce) +{ + switch (opcode) { + case ZEND_ADD: + return ce->__add; + break; + + case ZEND_SUB: + return ce->__sub; + break; + + case ZEND_MUL: + return ce->__mul; + break; + + case ZEND_DIV: + return ce->__div; + break; + + case ZEND_MOD: + return ce->__mod; + break; + + case ZEND_POW: + return ce->__pow; + break; + + case ZEND_BW_AND: + return ce->__bitwiseand; + break; + + case ZEND_BW_OR: + return ce->__bitwiseor; + break; + + case ZEND_BW_XOR: + return ce->__bitwisexor; + break; + + case ZEND_BW_NOT: + return ce->__bitwisenot; + break; + + case ZEND_SL: + return ce->__bitwiseshiftleft; + break; + + case ZEND_SR: + return ce->__bitwiseshiftright; + break; + + case ZEND_IS_EQUAL: + case ZEND_IS_NOT_EQUAL: + return ce->__equals; + break; + + case ZEND_IS_SMALLER: + case ZEND_IS_SMALLER_OR_EQUAL: + case ZEND_IS_LARGER: + case ZEND_IS_LARGER_OR_EQUAL: + case ZEND_SPACESHIP: + return ce->__compareto; + break; + + default: + return NULL; + } +} + ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has_set_exists, void **cache_slot) /* {{{ */ { int result; diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 53eef829282ce..61d653495c533 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -247,6 +247,10 @@ ZEND_API HashTable *zend_std_get_properties_for(zend_object *obj, zend_prop_purp * consumers of the get_properties_for API. */ ZEND_API HashTable *zend_get_properties_for(zval *obj, zend_prop_purpose purpose); +/* Helper functions for operator overloads for extensions */ +ZEND_API int zend_std_has_op_overload(zend_uchar opcode, zval *obj); +ZEND_API zend_function *zend_std_get_op_overload(zend_uchar opcode, zend_class_entry *ce); + #define zend_release_properties(ht) do { \ if ((ht) && !(GC_FLAGS(ht) & GC_IMMUTABLE) && !GC_DELREF(ht)) { \ zend_array_destroy(ht); \ From 3d33dddb47032877f3526e84bb594bb08e612cde Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Fri, 10 Dec 2021 23:03:19 -0800 Subject: [PATCH 34/36] Disallow direct method calls to operators --- .../operator_direct_method_call.phpt | 77 +++++++++++++++++++ Zend/zend_compile.h | 3 + Zend/zend_language_parser.y | 2 +- Zend/zend_vm_def.h | 15 ++++ Zend/zend_vm_execute.h | 45 +++++++++++ 5 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/operator_overloads/operator_direct_method_call.phpt diff --git a/Zend/tests/operator_overloads/operator_direct_method_call.phpt b/Zend/tests/operator_overloads/operator_direct_method_call.phpt new file mode 100644 index 0000000000000..fd1eaba5d050c --- /dev/null +++ b/Zend/tests/operator_overloads/operator_direct_method_call.phpt @@ -0,0 +1,77 @@ +--TEST-- +operator overload: disallowed method calls +--FILE-- +test(); + +$obj->{'test'}(); + +try { + $obj->{'+'}(1, OperandPosition::LeftSide); +} catch (Throwable $e) { + echo $e->getMessage().PHP_EOL; +} + +try { + $obj->$op(1, OperandPosition::LeftSide); +} catch (Throwable $e) { + echo $e->getMessage().PHP_EOL; +} + +try { + call_user_func([$obj, '+'], 1, OperandPosition::LeftSide); +} catch (Throwable $e) { + echo $e->getMessage().PHP_EOL; +} + +try { + eval('$obj->{\'+\'}(1, OperandPosition::LeftSide);'); +} catch (Throwable $e) { + echo $e->getMessage().PHP_EOL; +} + +try { + $callable = [$obj, '+']; + $callable(1, OperandPosition::LeftSide); +} catch (Throwable $e) { + echo $e->getMessage().PHP_EOL; +} + +try { + call_user_func(['A', '+'], 1, OperandPosition::LeftSide); +} catch (Throwable $e) { + echo $e->getMessage().PHP_EOL; +} + +try { + call_user_func('A::+', 1, OperandPosition::LeftSide); +} catch (Throwable $e) { + echo $e->getMessage().PHP_EOL; +} +?> +--EXPECT-- +test function +test function +Operator implementations may not be called as methods +Operator implementations may not be called as methods +Operator implementations may not be called as methods +Operator implementations may not be called as methods +Operator implementations may not be called as methods +call_user_func(): Argument #1 ($callback) must be a valid callback, non-static method A::+() cannot be called statically +call_user_func(): Argument #1 ($callback) must be a valid callback, non-static method A::+() cannot be called statically diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index f13a81e6a1054..e4d1ee981b931 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -357,6 +357,9 @@ typedef struct _zend_oparray_context { /* method flag used by Closure::__invoke() (int only) | | | */ #define ZEND_ACC_USER_ARG_INFO (1 << 26) /* | X | | */ /* | | | */ +/* method is an operator | | | */ +#define ZEND_ACC_OPERATOR (1 << 27) /* | X | | */ +/* | | | */ /* op_array uses strict mode types | | | */ #define ZEND_ACC_STRICT_TYPES (1U << 31) /* | X | | */ diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 6fd80dd4b0ccc..5b9526e0bfee2 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -934,7 +934,7 @@ attributed_class_statement: return_type backup_fn_flags method_body backup_fn_flags { zval zv; if (zend_lex_tstring(&zv, $3) == FAILURE) { YYABORT; } - $$ = zend_ast_create_decl(ZEND_AST_METHOD, $1 | $11, $2, $4, Z_STR(zv), $6, NULL, $10, $8, NULL); + $$ = zend_ast_create_decl(ZEND_AST_METHOD, $1 | $11 | ZEND_ACC_OPERATOR, $2, $4, Z_STR(zv), $6, NULL, $10, $8, NULL); CG(extra_fn_flags) = $9; } | enum_case { $$ = $1; } ; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 1542a32c675be..4a5b0ec52fc61 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4330,6 +4330,21 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL,OBSERVER)) SAVE_OPLINE(); EX(call) = call->prev_execute_data; + if (EXPECTED(fbc->common.fn_flags & ZEND_ACC_OPERATOR)) { + zend_vm_stack_free_args(call); + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(call->extra_named_params); + } + + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { + OBJ_RELEASE(Z_OBJ(call->This)); + } + + zend_vm_stack_free_call_frame(call); + zend_throw_error(NULL, "Operator implementations may not be called as methods"); + HANDLE_EXCEPTION(); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { ret = NULL; if (RETURN_VALUE_USED(opline)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 1e7d9ac020cf3..fe4f5d73e57d6 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1765,6 +1765,21 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV SAVE_OPLINE(); EX(call) = call->prev_execute_data; + if (EXPECTED(fbc->common.fn_flags & ZEND_ACC_OPERATOR)) { + zend_vm_stack_free_args(call); + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(call->extra_named_params); + } + + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { + OBJ_RELEASE(Z_OBJ(call->This)); + } + + zend_vm_stack_free_call_frame(call); + zend_throw_error(NULL, "Operator implementations may not be called as methods"); + HANDLE_EXCEPTION(); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { ret = NULL; if (0) { @@ -1874,6 +1889,21 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV SAVE_OPLINE(); EX(call) = call->prev_execute_data; + if (EXPECTED(fbc->common.fn_flags & ZEND_ACC_OPERATOR)) { + zend_vm_stack_free_args(call); + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(call->extra_named_params); + } + + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { + OBJ_RELEASE(Z_OBJ(call->This)); + } + + zend_vm_stack_free_call_frame(call); + zend_throw_error(NULL, "Operator implementations may not be called as methods"); + HANDLE_EXCEPTION(); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { ret = NULL; if (1) { @@ -1983,6 +2013,21 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBS SAVE_OPLINE(); EX(call) = call->prev_execute_data; + if (EXPECTED(fbc->common.fn_flags & ZEND_ACC_OPERATOR)) { + zend_vm_stack_free_args(call); + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(call->extra_named_params); + } + + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { + OBJ_RELEASE(Z_OBJ(call->This)); + } + + zend_vm_stack_free_call_frame(call); + zend_throw_error(NULL, "Operator implementations may not be called as methods"); + HANDLE_EXCEPTION(); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { ret = NULL; if (RETURN_VALUE_USED(opline)) { From 6395654f88bcd3663cbbf69290759efd46d0f894 Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Sat, 11 Dec 2021 01:26:39 -0800 Subject: [PATCH 35/36] Reflection support for operator overloads --- .../operator_reflection.phpt | 75 ++++++++++++++ ext/reflection/php_reflection.c | 99 ++++++++++++++++++- ext/reflection/php_reflection.stub.php | 12 +++ ext/reflection/php_reflection_arginfo.h | 18 +++- 4 files changed, 201 insertions(+), 3 deletions(-) create mode 100644 Zend/tests/operator_overloads/operator_reflection.phpt diff --git a/Zend/tests/operator_overloads/operator_reflection.phpt b/Zend/tests/operator_overloads/operator_reflection.phpt new file mode 100644 index 0000000000000..a7e2e58afb86e --- /dev/null +++ b/Zend/tests/operator_overloads/operator_reflection.phpt @@ -0,0 +1,75 @@ +--TEST-- +operator overload: reflection for operators +--FILE-- +hasMethod('test')); +var_dump($reflector->hasMethod('+')); +var_dump($reflector->hasOperator('test')); +var_dump($reflector->hasOperator('+')); + +var_dump(count($reflector->getMethods())); +var_dump(count($reflector->getOperators())); + +try { + var_dump($reflector->getMethod('+')); +} catch (Throwable $e) { + echo $e->getMessage().PHP_EOL; +} + +try { + var_dump($reflector->getOperator('test')); +} catch (Throwable $e) { + echo $e->getMessage().PHP_EOL; +} + +try { + var_dump($reflector->getMethod('blank')); +} catch (Throwable $e) { + echo $e->getMessage().PHP_EOL; +} + +try { + var_dump($reflector->getOperator('blank')); +} catch (Throwable $e) { + echo $e->getMessage().PHP_EOL; +} + +$operatorReflector = $reflector->getOperator('+'); +$testReflector = $reflector->getMethod('test'); + +var_dump($operatorReflector instanceof ReflectionMethod); +var_dump($operatorReflector->isOperator()); +var_dump($testReflector->isOperator()); + +?> +--EXPECT-- +bool(true) +bool(false) +bool(false) +bool(true) +int(1) +int(1) +Operator A::+() is not a method, use getOperator() +Operator A::test() does not exist +Method A::blank() does not exist +Operator A::blank() does not exist +bool(true) +bool(true) +bool(false) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 64cdc053f7638..7b92ff6831921 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -3386,6 +3386,13 @@ ZEND_METHOD(ReflectionMethod, invokeArgs) } /* }}} */ +/* {{{ Returns whether this method is final */ +ZEND_METHOD(ReflectionMethod, isOperator) +{ + _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_OPERATOR); +} +/* }}} */ + /* {{{ Returns whether this method is final */ ZEND_METHOD(ReflectionMethod, isFinal) { @@ -4327,7 +4334,12 @@ ZEND_METHOD(ReflectionClass, hasMethod) GET_REFLECTION_OBJECT_PTR(ce); lc_name = zend_string_tolower(name); - RETVAL_BOOL(zend_hash_exists(&ce->function_table, lc_name) || is_closure_invoke(ce, lc_name)); + zend_function *fptr = zend_hash_find_ptr(&ce->function_table, lc_name); + if (fptr == NULL || fptr->common.fn_flags & ZEND_ACC_OPERATOR) { + RETVAL_BOOL(0); + } else { + RETVAL_BOOL(zend_hash_exists(&ce->function_table, lc_name) || is_closure_invoke(ce, lc_name)); + } zend_string_release(lc_name); } /* }}} */ @@ -4347,7 +4359,11 @@ ZEND_METHOD(ReflectionClass, getMethod) GET_REFLECTION_OBJECT_PTR(ce); lc_name = zend_string_tolower(name); - if (!Z_ISUNDEF(intern->obj) && is_closure_invoke(ce, lc_name) + if ((mptr = zend_hash_find_ptr(&ce->function_table, lc_name)) != NULL + && mptr->common.fn_flags & ZEND_ACC_OPERATOR) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Operator %s::%s() is not a method, use getOperator()", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + } else if (!Z_ISUNDEF(intern->obj) && is_closure_invoke(ce, lc_name) && (mptr = zend_get_closure_invoke_method(Z_OBJ(intern->obj))) != NULL) { /* don't assign closure_object since we only reflect the invoke handler @@ -4405,6 +4421,9 @@ ZEND_METHOD(ReflectionClass, getMethods) array_init(return_value); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, mptr) { + if (mptr->common.fn_flags & ZEND_ACC_OPERATOR) { + continue; + } _addmethod(mptr, ce, Z_ARRVAL_P(return_value), filter); } ZEND_HASH_FOREACH_END(); @@ -4429,6 +4448,82 @@ ZEND_METHOD(ReflectionClass, getMethods) } /* }}} */ +/* {{{ Returns whether a method exists or not */ +ZEND_METHOD(ReflectionClass, hasOperator) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_string *name, *lc_name; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { + RETURN_THROWS(); + } + + GET_REFLECTION_OBJECT_PTR(ce); + lc_name = zend_string_tolower(name); + zend_function *fptr = zend_hash_find_ptr(&ce->function_table, lc_name); + if (fptr == NULL || fptr->common.fn_flags & ZEND_ACC_OPERATOR) { + RETVAL_BOOL(1); + } else { + RETVAL_BOOL(0); + } + zend_string_release(lc_name); +} +/* }}} */ + +/* {{{ Returns the class' method specified by its name */ +ZEND_METHOD(ReflectionClass, getOperator) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_function *mptr; + zend_string *name, *lc_name; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { + RETURN_THROWS(); + } + + GET_REFLECTION_OBJECT_PTR(ce); + lc_name = zend_string_tolower(name); + if ((mptr = zend_hash_find_ptr(&ce->function_table, lc_name)) != NULL + && mptr->common.fn_flags & ZEND_ACC_OPERATOR) { + reflection_method_factory(ce, mptr, NULL, return_value); + } else { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Operator %s::%s() does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + } + zend_string_release(lc_name); +} +/* }}} */ + +/* {{{ Returns an array of this class' methods */ +ZEND_METHOD(ReflectionClass, getOperators) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_function *mptr; + zend_long filter; + bool filter_is_null = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l!", &filter, &filter_is_null) == FAILURE) { + RETURN_THROWS(); + } + + if (filter_is_null) { + filter = ZEND_ACC_PPP_MASK | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL | ZEND_ACC_STATIC; + } + + GET_REFLECTION_OBJECT_PTR(ce); + + array_init(return_value); + ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, mptr) { + if (mptr->common.fn_flags & ZEND_ACC_OPERATOR) { + _addmethod(mptr, ce, Z_ARRVAL_P(return_value), filter); + } + } ZEND_HASH_FOREACH_END(); +} +/* }}} */ + /* {{{ Returns whether a property exists or not */ ZEND_METHOD(ReflectionClass, hasProperty) { diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index 8f2ef6ec6f44e..a13b1082bb141 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -165,6 +165,9 @@ public function __construct(object|string $objectOrMethod, ?string $method = nul public function __toString(): string {} + /** @tentative-return-type */ + public function isOperator(): bool {} + /** @tentative-return-type */ public function isPublic(): bool {} @@ -261,6 +264,15 @@ public function getMethod(string $name): ReflectionMethod {} /** @tentative-return-type */ public function getMethods(?int $filter = null): array {} + /** @tentative-return-type */ + public function hasOperator(string $name): bool {} + + /** @tentative-return-type */ + public function getOperator(string $name): ReflectionMethod {} + + /** @tentative-return-type */ + public function getOperators(?int $filter = null): array {} + /** @tentative-return-type */ public function hasProperty(string $name): bool {} diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index 12b01c4d264fd..68cacbabb510d 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 62fcf63d2f3e93537560c3a03e71fda131a31586 */ + * Stub hash: d0d3d62766e8f6d1c6a29a685433a32f064c558f */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0) @@ -131,6 +131,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionMethod___toString arginfo_class_ReflectionFunction___toString +#define arginfo_class_ReflectionMethod_isOperator arginfo_class_ReflectionFunctionAbstract_inNamespace + #define arginfo_class_ReflectionMethod_isPublic arginfo_class_ReflectionFunctionAbstract_inNamespace #define arginfo_class_ReflectionMethod_isPrivate arginfo_class_ReflectionFunctionAbstract_inNamespace @@ -214,6 +216,12 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, filter, IS_LONG, 1, "null") ZEND_END_ARG_INFO() +#define arginfo_class_ReflectionClass_hasOperator arginfo_class_ReflectionClass_hasMethod + +#define arginfo_class_ReflectionClass_getOperator arginfo_class_ReflectionClass_getMethod + +#define arginfo_class_ReflectionClass_getOperators arginfo_class_ReflectionClass_getMethods + #define arginfo_class_ReflectionClass_hasProperty arginfo_class_ReflectionClass_hasMethod ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionClass_getProperty, 0, 1, ReflectionProperty, 0) @@ -643,6 +651,7 @@ ZEND_METHOD(ReflectionGenerator, getThis); ZEND_METHOD(ReflectionGenerator, getExecutingGenerator); ZEND_METHOD(ReflectionMethod, __construct); ZEND_METHOD(ReflectionMethod, __toString); +ZEND_METHOD(ReflectionMethod, isOperator); ZEND_METHOD(ReflectionMethod, isPublic); ZEND_METHOD(ReflectionMethod, isPrivate); ZEND_METHOD(ReflectionMethod, isProtected); @@ -673,6 +682,9 @@ ZEND_METHOD(ReflectionClass, getConstructor); ZEND_METHOD(ReflectionClass, hasMethod); ZEND_METHOD(ReflectionClass, getMethod); ZEND_METHOD(ReflectionClass, getMethods); +ZEND_METHOD(ReflectionClass, hasOperator); +ZEND_METHOD(ReflectionClass, getOperator); +ZEND_METHOD(ReflectionClass, getOperators); ZEND_METHOD(ReflectionClass, hasProperty); ZEND_METHOD(ReflectionClass, getProperty); ZEND_METHOD(ReflectionClass, getProperties); @@ -901,6 +913,7 @@ static const zend_function_entry class_ReflectionGenerator_methods[] = { static const zend_function_entry class_ReflectionMethod_methods[] = { ZEND_ME(ReflectionMethod, __construct, arginfo_class_ReflectionMethod___construct, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionMethod, __toString, arginfo_class_ReflectionMethod___toString, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionMethod, isOperator, arginfo_class_ReflectionMethod_isOperator, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionMethod, isPublic, arginfo_class_ReflectionMethod_isPublic, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionMethod, isPrivate, arginfo_class_ReflectionMethod_isPrivate, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionMethod, isProtected, arginfo_class_ReflectionMethod_isProtected, ZEND_ACC_PUBLIC) @@ -937,6 +950,9 @@ static const zend_function_entry class_ReflectionClass_methods[] = { ZEND_ME(ReflectionClass, hasMethod, arginfo_class_ReflectionClass_hasMethod, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, getMethod, arginfo_class_ReflectionClass_getMethod, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, getMethods, arginfo_class_ReflectionClass_getMethods, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, hasOperator, arginfo_class_ReflectionClass_hasOperator, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, getOperator, arginfo_class_ReflectionClass_getOperator, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, getOperators, arginfo_class_ReflectionClass_getOperators, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, hasProperty, arginfo_class_ReflectionClass_hasProperty, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, getProperty, arginfo_class_ReflectionClass_getProperty, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, getProperties, arginfo_class_ReflectionClass_getProperties, ZEND_ACC_PUBLIC) From 8d1994fee02b351655c13831dcab1390e95645ce Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Sat, 11 Dec 2021 12:52:19 -0800 Subject: [PATCH 36/36] Allowing direct calls via closures --- .../operator_inheritance.phpt | 38 +++++++++++++++++++ .../operator_reflection.phpt | 5 +++ Zend/zend_vm_def.h | 3 +- Zend/zend_vm_execute.h | 9 +++-- 4 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 Zend/tests/operator_overloads/operator_inheritance.phpt diff --git a/Zend/tests/operator_overloads/operator_inheritance.phpt b/Zend/tests/operator_overloads/operator_inheritance.phpt new file mode 100644 index 0000000000000..e4c0c52486bda --- /dev/null +++ b/Zend/tests/operator_overloads/operator_inheritance.phpt @@ -0,0 +1,38 @@ +--TEST-- +operator overload: inheritance for operators +--FILE-- + +--EXPECT-- +The + method was called. diff --git a/Zend/tests/operator_overloads/operator_reflection.phpt b/Zend/tests/operator_overloads/operator_reflection.phpt index a7e2e58afb86e..136cf54d6ec78 100644 --- a/Zend/tests/operator_overloads/operator_reflection.phpt +++ b/Zend/tests/operator_overloads/operator_reflection.phpt @@ -58,6 +58,10 @@ var_dump($operatorReflector instanceof ReflectionMethod); var_dump($operatorReflector->isOperator()); var_dump($testReflector->isOperator()); +$closure = $operatorReflector->getClosure($obj); + +$closure(1, OperandPosition::LeftSide); + ?> --EXPECT-- bool(true) @@ -73,3 +77,4 @@ Operator A::blank() does not exist bool(true) bool(true) bool(false) +The + method was called. diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 2a14d5ebf276f..43e03e9e4e27c 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4390,7 +4390,8 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL,OBSERVER)) SAVE_OPLINE(); EX(call) = call->prev_execute_data; - if (EXPECTED(fbc->common.fn_flags & ZEND_ACC_OPERATOR)) { + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_OPERATOR) != 0) + && UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CLOSURE) == 0)) { zend_vm_stack_free_args(call); if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { zend_free_extra_named_params(call->extra_named_params); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index ba997d2c34bea..d7ffd9ae141cb 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1786,7 +1786,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV SAVE_OPLINE(); EX(call) = call->prev_execute_data; - if (EXPECTED(fbc->common.fn_flags & ZEND_ACC_OPERATOR)) { + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_OPERATOR) != 0) + && UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CLOSURE) == 0)) { zend_vm_stack_free_args(call); if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { zend_free_extra_named_params(call->extra_named_params); @@ -1910,7 +1911,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV SAVE_OPLINE(); EX(call) = call->prev_execute_data; - if (EXPECTED(fbc->common.fn_flags & ZEND_ACC_OPERATOR)) { + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_OPERATOR) != 0) + && UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CLOSURE) == 0)) { zend_vm_stack_free_args(call); if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { zend_free_extra_named_params(call->extra_named_params); @@ -2034,7 +2036,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBS SAVE_OPLINE(); EX(call) = call->prev_execute_data; - if (EXPECTED(fbc->common.fn_flags & ZEND_ACC_OPERATOR)) { + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_OPERATOR) != 0) + && UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_CLOSURE) == 0)) { zend_vm_stack_free_args(call); if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { zend_free_extra_named_params(call->extra_named_params);