From bee945b426b9803a64d96c43be0ce4ca86891b48 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sat, 8 Mar 2025 08:55:48 +0100 Subject: [PATCH 01/65] add new token --- Zend/zend_language_parser.y | 1 + Zend/zend_language_scanner.l | 4 ++++ ext/tokenizer/tokenizer_data.c | 1 + ext/tokenizer/tokenizer_data.stub.php | 5 +++++ 4 files changed, 11 insertions(+) diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 9483a83b4e955..3c4c1be7f8c36 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -232,6 +232,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_DOLLAR_OPEN_CURLY_BRACES "'${'" %token T_CURLY_OPEN "'{$'" %token T_PAAMAYIM_NEKUDOTAYIM "'::'" +%token T_INNER_REF "':>'" %token T_NS_SEPARATOR "'\\'" %token T_ELLIPSIS "'...'" %token T_COALESCE "'??'" diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 4c883b81c5f7d..729c096976afb 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -1601,6 +1601,10 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_ RETURN_TOKEN(T_PAAMAYIM_NEKUDOTAYIM); } +":>" { + RETURN_TOKEN(T_INNER_REF); +} + "..." { RETURN_TOKEN(T_ELLIPSIS); } diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index a1e131032bcfb..0f1bee1ee37bb 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -168,6 +168,7 @@ char *get_token_type_name(int token_type) case T_DOLLAR_OPEN_CURLY_BRACES: return "T_DOLLAR_OPEN_CURLY_BRACES"; case T_CURLY_OPEN: return "T_CURLY_OPEN"; case T_PAAMAYIM_NEKUDOTAYIM: return "T_DOUBLE_COLON"; + case T_INNER_REF: return "T_INNER_REF"; case T_NS_SEPARATOR: return "T_NS_SEPARATOR"; case T_ELLIPSIS: return "T_ELLIPSIS"; case T_COALESCE: return "T_COALESCE"; diff --git a/ext/tokenizer/tokenizer_data.stub.php b/ext/tokenizer/tokenizer_data.stub.php index c1e1fd254dfaa..089bd5736f9a7 100644 --- a/ext/tokenizer/tokenizer_data.stub.php +++ b/ext/tokenizer/tokenizer_data.stub.php @@ -717,6 +717,11 @@ * @cvalue T_PAAMAYIM_NEKUDOTAYIM */ const T_PAAMAYIM_NEKUDOTAYIM = UNKNOWN; +/** + * @var int + * @cvalue T_INNER_REF + */ +const T_INNER_REF = UNKNOWN; /** * @var int * @cvalue T_NS_SEPARATOR From 3d05dd7b3013fc0acbcae0634fe798188cc54b7b Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sat, 8 Mar 2025 09:21:56 +0100 Subject: [PATCH 02/65] create the new grammar --- Zend/zend_language_parser.y | 42 ++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 3c4c1be7f8c36..a991591d400f7 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -277,7 +277,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars %type lexical_var_list encaps_list %type array_pair non_empty_array_pair_list array_pair_list possible_array_pair -%type isset_variable type return_type type_expr type_without_static +%type isset_variable type return_type type_expr type_without_static inner_type_without_static %type identifier type_expr_without_static union_type_without_static_element union_type_without_static intersection_type_without_static %type inline_function union_type_element union_type intersection_type %type attributed_statement attributed_class_statement attributed_parameter @@ -286,7 +286,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type enum_declaration_statement enum_backing_type enum_case enum_case_expr %type function_name non_empty_member_modifiers %type property_hook property_hook_list optional_property_hook_list hooked_property property_hook_body -%type optional_parameter_list +%type optional_parameter_list inner_class_statement inner_class_modifiers inner_class_name_reference %type returns_ref function fn is_reference is_variadic property_modifiers property_hook_modifiers %type method_modifiers class_const_modifiers member_modifier optional_cpp_modifiers @@ -867,9 +867,16 @@ type_expr_without_static: ; type_without_static: - T_ARRAY { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_ARRAY); } - | T_CALLABLE { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_CALLABLE); } - | name { $$ = $1; } + T_ARRAY { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_ARRAY); } + | T_CALLABLE { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_CALLABLE); } + | inner_type_without_static { $$ = $1; } +; + +inner_type_without_static: + inner_type_without_static T_INNER_REF name + { $$ = zend_ast_create(ZEND_AST_INNER_CLASS, $1, $3); } + | name + { $$ = $1; } ; union_type_without_static_element: @@ -944,6 +951,18 @@ class_statement_list: { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } ; +inner_class_statement: + T_CLASS T_STRING { $$ = CG(zend_lineno); } extends_from implements_list backup_doc_comment '{' class_statement_list '}' + { $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, $3, $6, zend_ast_get_str($2), $4, $5, $8, NULL, NULL); } +; + +inner_class_modifiers: + non_empty_member_modifiers + { $$ = zend_modifier_list_to_flags(ZEND_MODIFIER_TARGET_INNER_CLASS, $1); + if (!$$) { YYERROR; } } + | %empty + { $$ = ZEND_ACC_PUBLIC; } +; attributed_class_statement: property_modifiers optional_type_without_static property_list ';' @@ -963,6 +982,8 @@ attributed_class_statement: { $$ = 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; } | enum_case { $$ = $1; } + | inner_class_modifiers inner_class_statement + { $$ = $2; $$->attr = $1; } ; class_statement: @@ -1415,11 +1436,16 @@ class_name: ; class_name_reference: - class_name { $$ = $1; } - | new_variable { $$ = $1; } - | '(' expr ')' { $$ = $2; } + inner_class_name_reference { $$ = $1; } + | new_variable { $$ = $1; } + | '(' expr ')' { $$ = $2; } ; +inner_class_name_reference: + class_name { $$ = $1; } + | inner_class_name_reference T_INNER_REF class_name + { $$ = zend_ast_create(ZEND_AST_INNER_CLASS, $1, $3); } + backticks_expr: %empty { $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); } From a815b8bd76be413c30302bfcccc0b2f9b82ac36f Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sat, 8 Mar 2025 09:34:39 +0100 Subject: [PATCH 03/65] add new ast pieces --- Zend/zend_ast.h | 1 + Zend/zend_compile.h | 1 + 2 files changed, 2 insertions(+) diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 9348c35f6cc07..557a8c669cf23 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -134,6 +134,7 @@ enum _zend_ast_kind { ZEND_AST_YIELD, ZEND_AST_COALESCE, ZEND_AST_ASSIGN_COALESCE, + ZEND_AST_INNER_CLASS, ZEND_AST_STATIC, ZEND_AST_WHILE, diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 224a68be749cb..0d3ccc2e066b4 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -894,6 +894,7 @@ typedef enum { ZEND_MODIFIER_TARGET_CONSTANT, ZEND_MODIFIER_TARGET_CPP, ZEND_MODIFIER_TARGET_PROPERTY_HOOK, + ZEND_MODIFIER_TARGET_INNER_CLASS, } zend_modifier_target; /* Used during AST construction */ From 978be06b5111060e97b5bec611549845ee017c34 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sat, 8 Mar 2025 09:59:30 +0100 Subject: [PATCH 04/65] handle modifiers --- Zend/zend_compile.c | 33 ++++++++++++++++++++++++++++ Zend/zend_language_parser.y | 4 ++-- tests/classes/inner_classes_001.phpt | 13 +++++++++++ tests/classes/inner_classes_002.phpt | 13 +++++++++++ tests/classes/inner_classes_003.phpt | 13 +++++++++++ tests/classes/inner_classes_004.phpt | 13 +++++++++++ tests/classes/inner_classes_005.phpt | 13 +++++++++++ tests/classes/inner_classes_006.phpt | 13 +++++++++++ 8 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 tests/classes/inner_classes_001.phpt create mode 100644 tests/classes/inner_classes_002.phpt create mode 100644 tests/classes/inner_classes_003.phpt create mode 100644 tests/classes/inner_classes_004.phpt create mode 100644 tests/classes/inner_classes_005.phpt create mode 100644 tests/classes/inner_classes_006.phpt diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 1cba9ef221997..b182a34ebe440 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -943,6 +943,8 @@ uint32_t zend_modifier_token_to_flag(zend_modifier_target target, uint32_t token member = "parameter"; } else if (target == ZEND_MODIFIER_TARGET_PROPERTY_HOOK) { member = "property hook"; + } else if (target == ZEND_MODIFIER_TARGET_INNER_CLASS) { + member = "inner class"; } else { ZEND_UNREACHABLE(); } @@ -1050,6 +1052,37 @@ uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag, zend_modifi return 0; } } + if (target == ZEND_MODIFIER_TARGET_INNER_CLASS) { + if ((flags & ZEND_ACC_PPP_MASK) && (new_flag & ZEND_ACC_PPP_MASK)) { + zend_throw_exception(zend_ce_compile_error, + "Multiple access type modifiers are not allowed", 0); + return 0; + } + + if ((flags & ZEND_ACC_STATIC) || (new_flag & ZEND_ACC_STATIC)) { + zend_throw_exception(zend_ce_compile_error, + "Static inner classes are not allowed", 0); + return 0; + } + + if ((flags & ZEND_ACC_PUBLIC_SET) || (new_flag & ZEND_ACC_PUBLIC_SET)) { + zend_throw_exception(zend_ce_compile_error, + "Public(set) inner classes are not allowed", 0); + return 0; + } + + if ((flags & ZEND_ACC_PROTECTED_SET) || (new_flag & ZEND_ACC_PROTECTED_SET)) { + zend_throw_exception(zend_ce_compile_error, + "Protected(set) inner classes are not allowed", 0); + return 0; + } + + if ((flags & ZEND_ACC_PRIVATE_SET) || (new_flag & ZEND_ACC_PRIVATE_SET)) { + zend_throw_exception(zend_ce_compile_error, + "Private(set) inner classes are not allowed", 0); + return 0; + } + } return new_flags; } /* }}} */ diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index a991591d400f7..add30781a6d36 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -286,10 +286,10 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type enum_declaration_statement enum_backing_type enum_case enum_case_expr %type function_name non_empty_member_modifiers %type property_hook property_hook_list optional_property_hook_list hooked_property property_hook_body -%type optional_parameter_list inner_class_statement inner_class_modifiers inner_class_name_reference +%type optional_parameter_list inner_class_statement inner_class_name_reference %type returns_ref function fn is_reference is_variadic property_modifiers property_hook_modifiers -%type method_modifiers class_const_modifiers member_modifier optional_cpp_modifiers +%type method_modifiers class_const_modifiers member_modifier optional_cpp_modifiers inner_class_modifiers %type class_modifiers class_modifier anonymous_class_modifiers anonymous_class_modifiers_optional use_type backup_fn_flags %type backup_lex_pos diff --git a/tests/classes/inner_classes_001.phpt b/tests/classes/inner_classes_001.phpt new file mode 100644 index 0000000000000..ac1ce71cd3d40 --- /dev/null +++ b/tests/classes/inner_classes_001.phpt @@ -0,0 +1,13 @@ +--TEST-- +multiple access modifiers +--FILE-- + +--EXPECTF-- +Fatal error: Multiple access type modifiers are not allowed in %s on line %d diff --git a/tests/classes/inner_classes_002.phpt b/tests/classes/inner_classes_002.phpt new file mode 100644 index 0000000000000..7e4fb38c3f2dd --- /dev/null +++ b/tests/classes/inner_classes_002.phpt @@ -0,0 +1,13 @@ +--TEST-- +invalid inner class +--FILE-- + +--EXPECTF-- +Fatal error: Multiple access type modifiers are not allowed in %s on line %d diff --git a/tests/classes/inner_classes_003.phpt b/tests/classes/inner_classes_003.phpt new file mode 100644 index 0000000000000..3dd79008daa60 --- /dev/null +++ b/tests/classes/inner_classes_003.phpt @@ -0,0 +1,13 @@ +--TEST-- +static access modifiers +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use the static modifier on a inner class in %s on line %d diff --git a/tests/classes/inner_classes_004.phpt b/tests/classes/inner_classes_004.phpt new file mode 100644 index 0000000000000..a4e86484ed9ec --- /dev/null +++ b/tests/classes/inner_classes_004.phpt @@ -0,0 +1,13 @@ +--TEST-- +public(set) inner class +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use the public(set) modifier on a inner class in %s on line %d diff --git a/tests/classes/inner_classes_005.phpt b/tests/classes/inner_classes_005.phpt new file mode 100644 index 0000000000000..82d7f0e93676c --- /dev/null +++ b/tests/classes/inner_classes_005.phpt @@ -0,0 +1,13 @@ +--TEST-- +protected(set) inner class +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use the protected(set) modifier on a inner class in %s on line %d diff --git a/tests/classes/inner_classes_006.phpt b/tests/classes/inner_classes_006.phpt new file mode 100644 index 0000000000000..41266b10b453f --- /dev/null +++ b/tests/classes/inner_classes_006.phpt @@ -0,0 +1,13 @@ +--TEST-- +private(set) inner class +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use the private(set) modifier on a inner class in %s on line %d From 466f6c84f1365790d65f90e215a26ebbc609a01d Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sat, 8 Mar 2025 12:24:08 +0100 Subject: [PATCH 05/65] handle compiling class declarations --- Zend/zend.h | 3 ++ Zend/zend_compile.c | 40 ++++++++++++++++++++++---- ext/tokenizer/tokenizer_data_arginfo.h | 1 + tests/classes/inner_classes_007.phpt | 21 ++++++++++++++ tests/classes/inner_classes_008.phpt | 13 +++++++++ 5 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 tests/classes/inner_classes_007.phpt create mode 100644 tests/classes/inner_classes_008.phpt diff --git a/Zend/zend.h b/Zend/zend.h index 0cf1faeb653fe..81ced0cf41a1d 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -164,6 +164,9 @@ struct _zend_class_entry { HashTable properties_info; HashTable constants_table; + zend_class_entry *required_scope; + char required_scope_absolute; + ZEND_MAP_PTR_DEF(zend_class_mutable_data*, mutable_data); zend_inheritance_cache_entry *inheritance_cache; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index b182a34ebe440..626339c348bd7 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -9090,10 +9090,6 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) if (EXPECTED((decl->flags & ZEND_ACC_ANON_CLASS) == 0)) { zend_string *unqualified_name = decl->name; - if (CG(active_class_entry)) { - zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be nested"); - } - const char *type = "a class name"; if (decl->flags & ZEND_ACC_ENUM) { type = "an enum name"; @@ -9103,7 +9099,41 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) type = "a trait name"; } zend_assert_valid_class_name(unqualified_name, type); - name = zend_prefix_with_ns(unqualified_name); + + if (CG(active_class_entry) && CG(active_op_array)->function_name) { + zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be declared inside functions"); + } + + if (CG(active_class_entry)) { + // rename the inner class so we may reference it by name + name = zend_string_concat3( + ZSTR_VAL(CG(active_class_entry)->name), ZSTR_LEN(CG(active_class_entry)->name), + ":>", 2, + ZSTR_VAL(unqualified_name), ZSTR_LEN(unqualified_name) + ); + + // configure the current ce->flags for a nested class. This should only include: + // - final + // - readonly + // - abstract + ce->ce_flags |= decl->attr & (ZEND_ACC_FINAL|ZEND_ACC_READONLY|ZEND_ACC_ABSTRACT); + + // configure the const stand-ins for a nested class. This should only include: + // - public + // - private + // - protected + int propFlags = decl->attr & (ZEND_ACC_PUBLIC|ZEND_ACC_PROTECTED|ZEND_ACC_PRIVATE); + + // if a class is private or protected, we need to require the correct scope + ce->required_scope = propFlags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED) ? CG(active_class_entry) : NULL; + ce->required_scope_absolute = propFlags & ZEND_ACC_PRIVATE ? true : false; + + // ensure the class is treated as a top-level class and not an anon class + toplevel = true; + } else { + name = zend_prefix_with_ns(unqualified_name); + ce->required_scope = NULL; + } name = zend_new_interned_string(name); lcname = zend_string_tolower(name); diff --git a/ext/tokenizer/tokenizer_data_arginfo.h b/ext/tokenizer/tokenizer_data_arginfo.h index 9c488d19f1890..3df94973e6cc2 100644 --- a/ext/tokenizer/tokenizer_data_arginfo.h +++ b/ext/tokenizer/tokenizer_data_arginfo.h @@ -146,6 +146,7 @@ static void register_tokenizer_data_symbols(int module_number) REGISTER_LONG_CONSTANT("T_DOLLAR_OPEN_CURLY_BRACES", T_DOLLAR_OPEN_CURLY_BRACES, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_CURLY_OPEN", T_CURLY_OPEN, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_PAAMAYIM_NEKUDOTAYIM", T_PAAMAYIM_NEKUDOTAYIM, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_INNER_REF", T_INNER_REF, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_NS_SEPARATOR", T_NS_SEPARATOR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_ELLIPSIS", T_ELLIPSIS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_COALESCE", T_COALESCE, CONST_PERSISTENT); diff --git a/tests/classes/inner_classes_007.phpt b/tests/classes/inner_classes_007.phpt new file mode 100644 index 0000000000000..8b53dd3b089b2 --- /dev/null +++ b/tests/classes/inner_classes_007.phpt @@ -0,0 +1,21 @@ +--TEST-- +simple declaration +--FILE-- +Middle')); +var_dump(class_exists('Outer:>Middle:>Inner')); +var_dump(class_exists(Outer:>Middle::class)); +var_dump(class_exists(Outer:>Middle:>Inner::class)); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/tests/classes/inner_classes_008.phpt b/tests/classes/inner_classes_008.phpt new file mode 100644 index 0000000000000..d129f17a7b0a5 --- /dev/null +++ b/tests/classes/inner_classes_008.phpt @@ -0,0 +1,13 @@ +--TEST-- +nested inside function +--FILE-- + +--EXPECTF-- +Fatal error: Class declarations may not be declared inside functions in %s on line %d From cbfc5bced6b9131ad5dab04181e9ba200541f634 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sat, 8 Mar 2025 21:27:45 +0100 Subject: [PATCH 06/65] add initial implementation; this adds all the initial opcode handling and special parts -- or the basics anyway. --- Zend/zend_compile.c | 39 ++ Zend/zend_opcode.c | 4 + Zend/zend_vm_def.h | 43 ++ Zend/zend_vm_execute.h | 290 +++++++++---- Zend/zend_vm_handlers.h | 921 ++++++++++++++++++++-------------------- Zend/zend_vm_opcodes.c | 6 +- Zend/zend_vm_opcodes.h | 3 +- 7 files changed, 752 insertions(+), 554 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 626339c348bd7..6a12e09cfc8fe 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2877,10 +2877,43 @@ static inline void zend_set_class_name_op1(zend_op *opline, znode *class_node) / } /* }}} */ +static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t fetch_flags); + +static void zend_compile_inner_class_ref(znode *result, zend_ast *ast) /* {{{ */ +{ + zend_ast *outer_class = ast->child[0]; + zend_ast *inner_class = ast->child[1]; + + znode outer_node, inner_node; + + // handle nesting + if (outer_class->kind == ZEND_AST_INNER_CLASS) { + zend_compile_inner_class_ref(&outer_node, outer_class); + } else { + zend_compile_class_ref(&outer_node, outer_class, ZEND_FETCH_CLASS_EXCEPTION); + } + + if (inner_class->kind == ZEND_AST_ZVAL && Z_TYPE_P(zend_ast_get_zval(inner_class)) == IS_STRING) { + ZVAL_STR(&inner_node.u.constant, zend_string_dup(Z_STR_P(zend_ast_get_zval(inner_class)), 0)); + inner_node.op_type = IS_CONST; + } else { + zend_compile_expr(&inner_node, inner_class); + } + + zend_op *opline = zend_emit_op(result, ZEND_FETCH_INNER_CLASS, &outer_node, &inner_node); + opline->extended_value = zend_alloc_cache_slot(); +} +/* }}} */ + static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t fetch_flags) /* {{{ */ { uint32_t fetch_type; + if (name_ast->kind == ZEND_AST_INNER_CLASS) { + zend_compile_inner_class_ref(result, name_ast); + return; + } + if (name_ast->kind != ZEND_AST_ZVAL) { znode name_node; @@ -9127,6 +9160,9 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) // if a class is private or protected, we need to require the correct scope ce->required_scope = propFlags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED) ? CG(active_class_entry) : NULL; ce->required_scope_absolute = propFlags & ZEND_ACC_PRIVATE ? true : false; + if (ce->required_scope) { + ce->required_scope->refcount ++; + } // ensure the class is treated as a top-level class and not an anon class toplevel = true; @@ -11783,6 +11819,9 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ case ZEND_AST_MATCH: zend_compile_match(result, ast); return; + case ZEND_AST_INNER_CLASS: + zend_compile_inner_class_ref(result, ast); + return; default: ZEND_ASSERT(0 /* not supported */); } diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index f32ae13e06793..b5ed1b7a9bc85 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -430,6 +430,10 @@ ZEND_API void destroy_zend_class(zval *zv) if (ce->backed_enum_table) { zend_hash_release(ce->backed_enum_table); } + if (ce->required_scope) { + ce->required_scope->refcount--; + ce->required_scope = NULL; + } break; case ZEND_INTERNAL_CLASS: if (ce->doc_comment) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 8770cab3826d8..7e5ec69a39d48 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1798,6 +1798,49 @@ ZEND_VM_C_LABEL(fetch_this): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR, CONST, CACHE_SLOT) +{ + USE_OPLINE + SAVE_OPLINE(); + + zend_string *inner_class_name, *full_class_name; + zend_class_entry *outer_ce = NULL, *inner_ce = NULL; + + if (OP1_TYPE == IS_CONST) { + zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); + outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv)); + if (!outer_ce) { + zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_P(outer_class_zv)); + HANDLE_EXCEPTION(); + } + } else { + outer_ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(outer_ce == NULL)) { + outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + } + + inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + + full_class_name = zend_string_concat3( + ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name), + ":>", 2, + ZSTR_VAL(inner_class_name), ZSTR_LEN(inner_class_name) + ); + + inner_ce = zend_lookup_class(full_class_name); + if (!inner_ce) { + zend_error(E_ERROR, "Class '%s' not found", ZSTR_VAL(full_class_name)); + } + + CACHE_PTR(opline->extended_value, inner_ce); + Z_CE_P(EX_VAR(opline->result.var)) = inner_ce; + + zend_string_release(full_class_name); + + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index e890f94cb08e2..36ae015622552 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6610,6 +6610,49 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CON ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + SAVE_OPLINE(); + + zend_string *inner_class_name, *full_class_name; + zend_class_entry *outer_ce = NULL, *inner_ce = NULL; + + if (IS_CONST == IS_CONST) { + zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); + outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv)); + if (!outer_ce) { + zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_P(outer_class_zv)); + HANDLE_EXCEPTION(); + } + } else { + outer_ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(outer_ce == NULL)) { + outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + } + + inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + + full_class_name = zend_string_concat3( + ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name), + ":>", 2, + ZSTR_VAL(inner_class_name), ZSTR_LEN(inner_class_name) + ); + + inner_ce = zend_lookup_class(full_class_name); + if (!inner_ce) { + zend_error(E_ERROR, "Class '%s' not found", ZSTR_VAL(full_class_name)); + } + + CACHE_PTR(opline->extended_value, inner_ce); + Z_CE_P(EX_VAR(opline->result.var)) = inner_ce; + + zend_string_release(full_class_name); + + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -16127,6 +16170,49 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HAN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + SAVE_OPLINE(); + + zend_string *inner_class_name, *full_class_name; + zend_class_entry *outer_ce = NULL, *inner_ce = NULL; + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); + outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv)); + if (!outer_ce) { + zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_P(outer_class_zv)); + HANDLE_EXCEPTION(); + } + } else { + outer_ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(outer_ce == NULL)) { + outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + } + + inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + + full_class_name = zend_string_concat3( + ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name), + ":>", 2, + ZSTR_VAL(inner_class_name), ZSTR_LEN(inner_class_name) + ); + + inner_ce = zend_lookup_class(full_class_name); + if (!inner_ce) { + zend_error(E_ERROR, "Class '%s' not found", ZSTR_VAL(full_class_name)); + } + + CACHE_PTR(opline->extended_value, inner_ce); + Z_CE_P(EX_VAR(opline->result.var)) = inner_ce; + + zend_string_release(full_class_name); + + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -57643,6 +57729,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER_LABEL, (void*)&&ZEND_JMP_FRAMELESS_SPEC_CONST_LABEL, (void*)&&ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_LABEL, + (void*)&&ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_LABEL, + (void*)&&ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_LABEL, + (void*)&&ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_FCALL_OFFSET_SPEC_CONST_LABEL, (void*)&&ZEND_RECV_NOTYPE_SPEC_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -59514,6 +59605,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_BOOL_XOR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_CONST_CONST) HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST): + VM_TRACE(ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST) + ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST) + HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CONST_CONST): VM_TRACE(ZEND_FETCH_DIM_R_SPEC_CONST_CONST) ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -60784,6 +60880,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_TMPVAR_CONST) HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST): + VM_TRACE(ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST) + ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST) + HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST): VM_TRACE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -66830,6 +66931,11 @@ void zend_vm_init(void) ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER_HANDLER, ZEND_JMP_FRAMELESS_SPEC_CONST_HANDLER, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_HANDLER, + ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_FCALL_OFFSET_SPEC_CONST_HANDLER, ZEND_RECV_NOTYPE_SPEC_HANDLER, ZEND_NULL_HANDLER, @@ -67787,7 +67893,7 @@ void zend_vm_init(void) 1255, 1256 | SPEC_RULE_OP1, 1261 | SPEC_RULE_OP1, - 3486, + 3491, 1266 | SPEC_RULE_OP1, 1271 | SPEC_RULE_OP1, 1276 | SPEC_RULE_OP2, @@ -67821,7 +67927,7 @@ void zend_vm_init(void) 1559 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1584 | SPEC_RULE_OP1, 1589, - 3486, + 3491, 1590 | SPEC_RULE_OP1, 1595 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1620 | SPEC_RULE_OP1 | SPEC_RULE_OP2, @@ -67952,52 +68058,52 @@ void zend_vm_init(void) 2573 | SPEC_RULE_OBSERVER, 2575, 2576, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, - 3486, + 2577 | SPEC_RULE_OP1, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, + 3491, }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -68170,7 +68276,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 = 2585 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2590 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -68178,7 +68284,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 = 2610 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2615 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -68186,7 +68292,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 = 2635 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2640 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -68197,17 +68303,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 = 2660 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2665 | 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 = 2685 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2690 | 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 = 2710 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2715 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -68218,17 +68324,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 = 2735 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2740 | 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 = 2760 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2765 | 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 = 2785 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2790 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_IDENTICAL: @@ -68239,14 +68345,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 = 2810 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2815 | 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 = 2885 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2890 | 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 = 3110 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3115 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_IDENTICAL: @@ -68257,14 +68363,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 = 2960 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2965 | 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 = 3035 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3040 | 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 = 3115 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3120 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_EQUAL: @@ -68275,12 +68381,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 = 2810 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2815 | 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 = 2885 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2890 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_EQUAL: @@ -68291,12 +68397,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 = 2960 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2965 | 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 = 3035 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3040 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_SMALLER: @@ -68304,12 +68410,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 = 3120 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3125 | 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 = 3195 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3200 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -68317,79 +68423,79 @@ 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 = 3270 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3275 | 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 = 3345 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3350 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_LONG) { - spec = 3432 | SPEC_RULE_OP1; - } else if (op1_info == MAY_BE_DOUBLE) { spec = 3437 | 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))))) { + } else if (op1_info == MAY_BE_DOUBLE) { spec = 3442 | 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 = 3447 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3420 | SPEC_RULE_RETVAL; + spec = 3425 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3422 | SPEC_RULE_RETVAL; + spec = 3427 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3424 | SPEC_RULE_RETVAL; + spec = 3429 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3426 | SPEC_RULE_RETVAL; + spec = 3431 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3428; + spec = 3433; } else if (op1_info == MAY_BE_LONG) { - spec = 3429; + spec = 3434; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3430; + spec = 3435; } else if (op1_info == MAY_BE_LONG) { - spec = 3431; + spec = 3436; } break; case ZEND_JMP: if (OP_JMP_ADDR(op, op->op1) > op) { - spec = 2584; + spec = 2589; } break; case ZEND_INIT_FCALL: if (Z_EXTRA_P(RT_CONSTANT(op, op->op2)) != 0) { - spec = 2577; + spec = 2582; } break; case ZEND_RECV: if (op->op2.num == MAY_BE_ANY) { - spec = 2578; + spec = 2583; } 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 = 3482; + spec = 3487; } 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 = 3477 | SPEC_RULE_OP1; + spec = 3482 | 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 = 3484 | SPEC_RULE_RETVAL; + spec = 3489 | SPEC_RULE_RETVAL; } break; case ZEND_FETCH_DIM_R: @@ -68397,22 +68503,22 @@ 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 = 3447 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3452 | 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 = 3483; + spec = 3488; } break; case ZEND_SEND_VAR: if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3472 | SPEC_RULE_OP1; + spec = 3477 | SPEC_RULE_OP1; } break; case ZEND_COUNT: if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 2579 | SPEC_RULE_OP1; + spec = 2584 | SPEC_RULE_OP1; } break; case ZEND_BW_OR: diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index 7f3a3cb5de260..3bf5234bf696d 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -1372,502 +1372,505 @@ _(2574, ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER) \ _(2575, ZEND_JMP_FRAMELESS_SPEC_CONST) \ _(2576, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED) \ - _(2577, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ - _(2578, ZEND_RECV_NOTYPE_SPEC) \ - _(2580, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ - _(2581, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ - _(2583, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \ - _(2584, ZEND_JMP_FORWARD_SPEC) \ - _(2590, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2591, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2592, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2594, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2577, ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST) \ + _(2578, ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST) \ + _(2579, ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST) \ + _(2582, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ + _(2583, ZEND_RECV_NOTYPE_SPEC) \ + _(2585, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ + _(2586, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ + _(2588, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \ + _(2589, ZEND_JMP_FORWARD_SPEC) \ _(2595, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(2596, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2597, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2599, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2605, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2606, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2607, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2609, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2615, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2616, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2617, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2619, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2600, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2601, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2602, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2604, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2610, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2611, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2612, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2614, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2620, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ _(2621, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2622, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2624, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2630, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2631, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2632, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2634, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2640, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2641, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2642, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2644, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2625, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2626, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2627, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2629, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2635, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2636, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2637, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2639, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2645, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ _(2646, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2647, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2649, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2655, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2656, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2657, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2659, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2661, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2662, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2664, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2665, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2667, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2669, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2650, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2651, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2652, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2654, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2660, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2661, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2662, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2664, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2667, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2669, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ _(2670, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(2671, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2672, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2674, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2680, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2681, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2682, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2684, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2686, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2687, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2689, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2690, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2691, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2692, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2694, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2675, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2676, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2677, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2679, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2685, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2686, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2687, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2689, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2691, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2692, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2694, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ _(2695, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ _(2696, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2697, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2699, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2705, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2706, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2707, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2709, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2711, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2712, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2714, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2715, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2716, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2717, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2719, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2700, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2701, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2702, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2704, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2710, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2711, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2712, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2714, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2716, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2717, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2719, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ _(2720, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ _(2721, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2722, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2724, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2730, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2731, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2732, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2734, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2740, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2741, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2742, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2744, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2725, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2726, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2727, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2729, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2735, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2736, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2737, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2739, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2745, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(2746, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2747, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2749, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2755, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2756, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2757, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2759, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2765, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2766, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2767, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2769, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2750, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2751, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2752, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2754, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2760, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2761, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2762, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2764, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2770, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ _(2771, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2772, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2774, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2780, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2781, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2782, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2784, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2790, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2791, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2792, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2794, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2775, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2776, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2777, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2779, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2785, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2786, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2787, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2789, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2795, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ _(2796, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2797, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2799, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2805, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2806, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2807, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2809, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2825, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2831, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2837, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2841, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_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) \ - _(2846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2847, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2852, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2870, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2871, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2872, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2873, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2874, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2875, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2876, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2877, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2878, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2882, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2883, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2884, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2900, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2906, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2912, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2916, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_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) \ - _(2921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2922, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2927, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2945, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2946, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2947, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2948, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2949, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2950, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2951, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2952, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2953, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2957, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2958, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2959, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2975, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2981, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2987, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2991, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_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) \ - _(2996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2997, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3002, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3020, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3021, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3022, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3023, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3024, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3025, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3026, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3027, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3028, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3032, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3033, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3034, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3050, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3056, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3062, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3066, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_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) \ - _(3071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3072, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3077, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3095, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3096, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3097, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3098, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3099, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3100, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3101, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3102, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3103, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3107, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3108, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3109, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3110, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3114, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3115, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3119, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3123, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3124, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3125, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3126, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3127, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3128, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3132, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3133, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3134, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3135, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3136, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3137, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3138, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3139, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_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) \ - _(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3157, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3158, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3162, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3163, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3164, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3180, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3181, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3182, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3183, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3184, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3185, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3186, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3187, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3188, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3192, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3193, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3194, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3198, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3202, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3207, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3208, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3209, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3211, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_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) \ - _(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3232, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3233, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3237, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3238, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3239, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3255, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3256, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3257, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3258, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3259, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3260, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3261, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3262, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3263, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3267, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3268, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3269, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3273, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3277, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3282, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3283, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3284, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3286, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_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) \ - _(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3307, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3308, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3312, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3313, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3314, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3330, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3331, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3332, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3333, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3334, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3335, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3336, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3337, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3338, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3342, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3343, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3344, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3348, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3352, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3357, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3358, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3359, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3361, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_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) \ - _(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3382, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3383, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3387, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3388, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3389, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3405, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3406, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3407, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3408, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3409, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3410, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3411, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3412, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3413, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3417, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3418, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3419, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3420, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3421, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3422, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3423, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ - _(3424, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3425, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3426, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3427, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ - _(3428, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3429, ZEND_POST_INC_LONG_SPEC_CV) \ - _(3430, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3431, ZEND_POST_DEC_LONG_SPEC_CV) \ - _(3432, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ - _(3433, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3434, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3436, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3437, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ - _(3438, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3439, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3441, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3442, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ - _(3443, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3444, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3446, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3448, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3449, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3451, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3452, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ - _(3453, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3454, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(2800, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2801, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2802, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2804, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2810, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2811, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2812, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2814, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2831, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2835, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2836, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2837, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2847, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2849, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2850, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2851, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2852, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2857, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2858, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2859, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2875, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2876, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2877, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2878, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2879, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2880, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2881, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2882, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2883, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2887, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2888, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2889, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2906, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2910, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2911, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2912, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2922, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2924, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2925, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2926, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2927, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2932, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2933, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2934, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2950, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2951, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2952, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2953, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2954, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2955, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2956, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2957, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2958, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2962, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2963, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2964, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2981, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2985, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2986, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2987, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2997, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2999, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3000, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3001, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3002, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3007, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3008, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3009, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3025, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3026, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3027, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3028, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3029, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3030, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3031, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3032, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3033, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3037, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3038, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3039, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3056, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3060, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3061, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3062, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3072, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3074, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3075, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3076, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3077, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3082, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3083, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3084, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3100, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3101, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3102, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3103, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3104, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3105, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3106, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3107, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3108, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3112, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3113, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3114, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3115, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3119, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3120, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3124, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3128, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3129, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3130, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3131, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3132, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3133, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3137, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3138, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3139, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3146, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3153, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3157, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3158, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3159, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3160, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3161, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3162, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3163, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3167, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3168, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3169, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3185, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3186, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3187, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3188, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3189, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3190, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3191, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3192, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3193, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3197, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3198, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3199, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3204, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3206, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3207, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3208, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3221, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3228, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3232, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3233, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3234, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3235, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3236, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3237, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3238, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3242, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3243, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3244, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3260, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3261, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3262, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3263, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3264, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3265, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3266, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3267, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3268, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3272, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3273, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3274, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3279, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3281, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3282, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3283, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3296, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3303, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3307, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3308, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3309, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3310, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3311, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3312, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3313, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3317, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3318, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3319, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3335, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3336, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3337, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3338, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3339, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3340, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3341, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3342, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3343, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3347, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3348, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3349, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3354, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3356, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3357, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3358, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3371, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3378, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3382, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3383, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3384, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3385, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3386, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3387, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3388, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3392, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3393, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3394, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3410, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3411, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3412, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3413, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3414, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3415, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3416, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3417, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3418, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3422, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3423, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3424, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3425, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3426, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3427, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3428, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ + _(3429, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3430, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3431, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3432, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ + _(3433, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3434, ZEND_POST_INC_LONG_SPEC_CV) \ + _(3435, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3436, ZEND_POST_DEC_LONG_SPEC_CV) \ + _(3437, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ + _(3438, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3439, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3441, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3442, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ + _(3443, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3444, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3446, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3447, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ + _(3448, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3449, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3451, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3453, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3454, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ _(3457, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ _(3458, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3459, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3461, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3467, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ - _(3468, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3469, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3471, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3474, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ - _(3476, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ - _(3479, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ - _(3481, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ - _(3482, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ - _(3483, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ - _(3484, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ - _(3485, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ - _(3485+1, ZEND_NULL) + _(3462, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3463, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3464, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3466, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3472, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3473, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3474, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3476, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3479, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ + _(3481, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ + _(3484, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ + _(3486, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ + _(3487, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ + _(3488, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ + _(3489, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ + _(3490, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ + _(3490+1, ZEND_NULL) diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 202dfd3f734f3..b1e6c2950fd6d 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[210] = { +static const char *zend_vm_opcodes_names[211] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -233,9 +233,10 @@ static const char *zend_vm_opcodes_names[210] = { "ZEND_FRAMELESS_ICALL_3", "ZEND_JMP_FRAMELESS", "ZEND_INIT_PARENT_PROPERTY_HOOK_CALL", + "ZEND_FETCH_INNER_CLASS", }; -static uint32_t zend_vm_opcodes_flags[210] = { +static uint32_t zend_vm_opcodes_flags[211] = { 0x00000000, 0x00000b0b, 0x00000b0b, @@ -446,6 +447,7 @@ static uint32_t zend_vm_opcodes_flags[210] = { 0x00000000, 0x01042003, 0x01001103, + 0x00040307, }; ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(uint8_t opcode) { diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index d472b5b9660f5..9734d26ee768e 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -291,7 +291,8 @@ END_EXTERN_C() #define ZEND_FRAMELESS_ICALL_3 207 #define ZEND_JMP_FRAMELESS 208 #define ZEND_INIT_PARENT_PROPERTY_HOOK_CALL 209 +#define ZEND_FETCH_INNER_CLASS 210 -#define ZEND_VM_LAST_OPCODE 209 +#define ZEND_VM_LAST_OPCODE 210 #endif From d9e9ccfa8384b76f1cec0f109d6569ae9d561c68 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sun, 9 Mar 2025 09:46:32 +0100 Subject: [PATCH 07/65] get return types working --- Zend/zend_compile.c | 33 ++++++++++++++++++++++++++++ Zend/zend_language_parser.y | 11 ++++------ tests/classes/inner_classes_009.phpt | 20 +++++++++++++++++ tests/classes/inner_classes_010.phpt | 18 +++++++++++++++ 4 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 tests/classes/inner_classes_009.phpt create mode 100644 tests/classes/inner_classes_010.phpt diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 6a12e09cfc8fe..de01738021d8c 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7018,6 +7018,36 @@ ZEND_API void zend_set_function_arg_flags(zend_function *func) /* {{{ */ } /* }}} */ +static zend_string *zend_resolve_nested_class_name(zend_ast *ast) +{ + ZEND_ASSERT(ast->kind == ZEND_AST_INNER_CLASS); + + zend_ast *outer_class = ast->child[0]; + zend_ast *inner_class = ast->child[1]; + + zend_string *outer_name, *inner_name, *full_name; + + if (outer_class->kind == ZEND_AST_INNER_CLASS) { + full_name = zend_resolve_nested_class_name(outer_class); + } else { + zval outer_class_name; + zend_try_compile_const_expr_resolve_class_name(&outer_class_name, outer_class); + outer_name = Z_STR(outer_class_name); + } + + inner_name = zend_ast_get_str(inner_class); + + full_name = zend_string_concat3( + ZSTR_VAL(outer_name), ZSTR_LEN(outer_name), + ":>", 2, + ZSTR_VAL(inner_name), ZSTR_LEN(inner_name) + ); + + zend_string_release(outer_name); + + return full_name; +} + static zend_type zend_compile_single_typename(zend_ast *ast) { ZEND_ASSERT(!(ast->attr & ZEND_TYPE_NULLABLE)); @@ -7382,6 +7412,9 @@ static zend_type zend_compile_typename_ex( ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_INTERSECTION_BIT; ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_ARENA_BIT; } + } else if (ast->kind == ZEND_AST_INNER_CLASS) { + zend_string *name = zend_resolve_nested_class_name(ast); + return (zend_type) ZEND_TYPE_INIT_CLASS(name, /* allow null */ false, 0); } else { type = zend_compile_single_typename(ast); } diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index add30781a6d36..02f1263e844a0 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -286,7 +286,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type enum_declaration_statement enum_backing_type enum_case enum_case_expr %type function_name non_empty_member_modifiers %type property_hook property_hook_list optional_property_hook_list hooked_property property_hook_body -%type optional_parameter_list inner_class_statement inner_class_name_reference +%type optional_parameter_list inner_class_statement %type returns_ref function fn is_reference is_variadic property_modifiers property_hook_modifiers %type method_modifiers class_const_modifiers member_modifier optional_cpp_modifiers inner_class_modifiers @@ -1433,19 +1433,16 @@ class_name: { zval zv; ZVAL_INTERNED_STR(&zv, ZSTR_KNOWN(ZEND_STR_STATIC)); $$ = zend_ast_create_zval_ex(&zv, ZEND_NAME_NOT_FQ); } | name { $$ = $1; } + | class_name T_INNER_REF name + { $$ = zend_ast_create(ZEND_AST_INNER_CLASS, $1, $3); } ; class_name_reference: - inner_class_name_reference { $$ = $1; } + class_name { $$ = $1; } | new_variable { $$ = $1; } | '(' expr ')' { $$ = $2; } ; -inner_class_name_reference: - class_name { $$ = $1; } - | inner_class_name_reference T_INNER_REF class_name - { $$ = zend_ast_create(ZEND_AST_INNER_CLASS, $1, $3); } - backticks_expr: %empty { $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); } diff --git a/tests/classes/inner_classes_009.phpt b/tests/classes/inner_classes_009.phpt new file mode 100644 index 0000000000000..13c84de709caa --- /dev/null +++ b/tests/classes/inner_classes_009.phpt @@ -0,0 +1,20 @@ +--TEST-- +basic nested classes +--FILE-- +Middle:>Inner()->test(); +?> +--EXPECT-- +Foo\Outer:>Middle:>Inner diff --git a/tests/classes/inner_classes_010.phpt b/tests/classes/inner_classes_010.phpt new file mode 100644 index 0000000000000..d7190df3644d0 --- /dev/null +++ b/tests/classes/inner_classes_010.phpt @@ -0,0 +1,18 @@ +--TEST-- +test return types +--FILE-- +Inner { + return new Outer:>Inner(); + } + } +} + +var_dump(Outer:>Inner::test()); +?> +--EXPECT-- +object(Outer:>Inner)#1 (0) { +} From aa6d3e944c778b579bfbaac3e53c745dc7453b6d Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sun, 9 Mar 2025 14:15:22 +0100 Subject: [PATCH 08/65] make ::class work --- Zend/zend_compile.c | 74 +++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index de01738021d8c..473d382ecdf4c 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1820,11 +1820,49 @@ static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */ } /* }}} */ +static bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *class_ast); + +static zend_string *zend_resolve_nested_class_name(zend_ast *ast) /* {{{ */ +{ + ZEND_ASSERT(ast->kind == ZEND_AST_INNER_CLASS); + + zend_ast *outer_class = ast->child[0]; + zend_ast *inner_class = ast->child[1]; + + zend_string *outer_name, *inner_name, *full_name; + + if (outer_class->kind == ZEND_AST_INNER_CLASS) { + outer_name = zend_resolve_nested_class_name(outer_class); + } else { + zval outer_class_name; + zend_try_compile_const_expr_resolve_class_name(&outer_class_name, outer_class); + outer_name = Z_STR(outer_class_name); + } + + inner_name = zend_ast_get_str(inner_class); + + full_name = zend_string_concat3( + ZSTR_VAL(outer_name), ZSTR_LEN(outer_name), + ":>", 2, + ZSTR_VAL(inner_name), ZSTR_LEN(inner_name) + ); + + zend_string_release(outer_name); + + return full_name; +} +/* }}} */ + static bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *class_ast) /* {{{ */ { uint32_t fetch_type; zval *class_name; + if (class_ast->kind == ZEND_AST_INNER_CLASS) { + ZVAL_STR(zv, zend_resolve_nested_class_name(class_ast)); + return 1; + } + if (class_ast->kind != ZEND_AST_ZVAL) { return 0; } @@ -7018,36 +7056,6 @@ ZEND_API void zend_set_function_arg_flags(zend_function *func) /* {{{ */ } /* }}} */ -static zend_string *zend_resolve_nested_class_name(zend_ast *ast) -{ - ZEND_ASSERT(ast->kind == ZEND_AST_INNER_CLASS); - - zend_ast *outer_class = ast->child[0]; - zend_ast *inner_class = ast->child[1]; - - zend_string *outer_name, *inner_name, *full_name; - - if (outer_class->kind == ZEND_AST_INNER_CLASS) { - full_name = zend_resolve_nested_class_name(outer_class); - } else { - zval outer_class_name; - zend_try_compile_const_expr_resolve_class_name(&outer_class_name, outer_class); - outer_name = Z_STR(outer_class_name); - } - - inner_name = zend_ast_get_str(inner_class); - - full_name = zend_string_concat3( - ZSTR_VAL(outer_name), ZSTR_LEN(outer_name), - ":>", 2, - ZSTR_VAL(inner_name), ZSTR_LEN(inner_name) - ); - - zend_string_release(outer_name); - - return full_name; -} - static zend_type zend_compile_single_typename(zend_ast *ast) { ZEND_ASSERT(!(ast->attr & ZEND_TYPE_NULLABLE)); @@ -11852,9 +11860,9 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ case ZEND_AST_MATCH: zend_compile_match(result, ast); return; - case ZEND_AST_INNER_CLASS: - zend_compile_inner_class_ref(result, ast); - return; + case ZEND_AST_INNER_CLASS: + zend_compile_inner_class_ref(result, ast); + return; default: ZEND_ASSERT(0 /* not supported */); } From bb94414adea124666f7cc123412c65e79750d8b4 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sun, 9 Mar 2025 14:16:19 +0100 Subject: [PATCH 09/65] fix failing test --- tests/classes/inner_classes_002.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/classes/inner_classes_002.phpt b/tests/classes/inner_classes_002.phpt index 7e4fb38c3f2dd..9c9eee89387b0 100644 --- a/tests/classes/inner_classes_002.phpt +++ b/tests/classes/inner_classes_002.phpt @@ -10,4 +10,4 @@ class Outer { ?> --EXPECTF-- -Fatal error: Multiple access type modifiers are not allowed in %s on line %d +Parse error: syntax error, unexpected identifier "int", expecting "class" in %s on line %d From b2581f40fd53490ece7cc009ba5d87b7da02cf4b Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sun, 9 Mar 2025 14:20:09 +0100 Subject: [PATCH 10/65] add another class --- tests/classes/inner_classes_011.phpt | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tests/classes/inner_classes_011.phpt diff --git a/tests/classes/inner_classes_011.phpt b/tests/classes/inner_classes_011.phpt new file mode 100644 index 0000000000000..e656a9648a2ca --- /dev/null +++ b/tests/classes/inner_classes_011.phpt @@ -0,0 +1,30 @@ +--TEST-- +::class, statics, and inner classes +--FILE-- +Middle::class); +var_dump(Outer:>Middle::FOO); +var_dump(Outer:>Middle::$bar); +var_dump(Outer:>Middle:>Inner::class); +var_dump(Outer:>Middle:>Inner::FOO); +var_dump(Outer:>Middle:>Inner::$bar); +?> +--EXPECT-- +string(13) "Outer:>Middle" +string(3) "foo" +int(42) +string(20) "Outer:>Middle:>Inner" +string(3) "foo" +int(42) From 787dd8ed3cf72fd9725a85f1de31cd9c35e238cb Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sun, 9 Mar 2025 17:39:27 +0100 Subject: [PATCH 11/65] add more tests to validate scope resolution keywords --- Zend/zend_compile.c | 68 +++++------ Zend/zend_vm_def.h | 38 ++++++- Zend/zend_vm_execute.h | 161 ++++++++++++++++++++++++++- Zend/zend_vm_handlers.h | 1 + tests/classes/inner_classes_012.phpt | 43 +++++++ 5 files changed, 275 insertions(+), 36 deletions(-) create mode 100644 tests/classes/inner_classes_012.phpt diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 473d382ecdf4c..203cf34f03444 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1793,33 +1793,6 @@ static uint32_t zend_get_class_fetch_type_ast(zend_ast *name_ast) /* {{{ */ } /* }}} */ -static zend_string *zend_resolve_const_class_name_reference(zend_ast *ast, const char *type) -{ - zend_string *class_name = zend_ast_get_str(ast); - if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type_ast(ast)) { - zend_error_noreturn(E_COMPILE_ERROR, - "Cannot use \"%s\" as %s, as it is reserved", - ZSTR_VAL(class_name), type); - } - return zend_resolve_class_name(class_name, ast->attr); -} - -static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */ -{ - if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && zend_is_scope_known()) { - zend_class_entry *ce = CG(active_class_entry); - if (!ce) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot use \"%s\" when no class scope is active", - fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : - fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); - } else if (fetch_type == ZEND_FETCH_CLASS_PARENT && !ce->parent_name) { - zend_error_noreturn(E_COMPILE_ERROR, - "Cannot use \"parent\" when current class scope has no parent"); - } - } -} -/* }}} */ - static bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *class_ast); static zend_string *zend_resolve_nested_class_name(zend_ast *ast) /* {{{ */ @@ -1853,6 +1826,37 @@ static zend_string *zend_resolve_nested_class_name(zend_ast *ast) /* {{{ */ } /* }}} */ +static zend_string *zend_resolve_const_class_name_reference(zend_ast *ast, const char *type) +{ + if (ast->kind == ZEND_AST_INNER_CLASS) { + return zend_resolve_nested_class_name(ast); + } + + zend_string *class_name = zend_ast_get_str(ast); + if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type_ast(ast)) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot use \"%s\" as %s, as it is reserved", + ZSTR_VAL(class_name), type); + } + return zend_resolve_class_name(class_name, ast->attr); +} + +static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */ +{ + if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && zend_is_scope_known()) { + zend_class_entry *ce = CG(active_class_entry); + if (!ce) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use \"%s\" when no class scope is active", + fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : + fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); + } else if (fetch_type == ZEND_FETCH_CLASS_PARENT && !ce->parent_name) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot use \"parent\" when current class scope has no parent"); + } + } +} +/* }}} */ + static bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *class_ast) /* {{{ */ { uint32_t fetch_type; @@ -2917,7 +2921,7 @@ static inline void zend_set_class_name_op1(zend_op *opline, znode *class_node) / static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t fetch_flags); -static void zend_compile_inner_class_ref(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_inner_class_ref(znode *result, zend_ast *ast, uint32_t fetch_flags) /* {{{ */ { zend_ast *outer_class = ast->child[0]; zend_ast *inner_class = ast->child[1]; @@ -2926,9 +2930,9 @@ static void zend_compile_inner_class_ref(znode *result, zend_ast *ast) /* {{{ */ // handle nesting if (outer_class->kind == ZEND_AST_INNER_CLASS) { - zend_compile_inner_class_ref(&outer_node, outer_class); + zend_compile_inner_class_ref(&outer_node, outer_class, fetch_flags); } else { - zend_compile_class_ref(&outer_node, outer_class, ZEND_FETCH_CLASS_EXCEPTION); + zend_compile_class_ref(&outer_node, outer_class, fetch_flags); } if (inner_class->kind == ZEND_AST_ZVAL && Z_TYPE_P(zend_ast_get_zval(inner_class)) == IS_STRING) { @@ -2948,7 +2952,7 @@ static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t f uint32_t fetch_type; if (name_ast->kind == ZEND_AST_INNER_CLASS) { - zend_compile_inner_class_ref(result, name_ast); + zend_compile_inner_class_ref(result, name_ast, fetch_flags); return; } @@ -11861,7 +11865,7 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ zend_compile_match(result, ast); return; case ZEND_AST_INNER_CLASS: - zend_compile_inner_class_ref(result, ast); + zend_compile_inner_class_ref(result, ast, ZEND_FETCH_CLASS_EXCEPTION); return; default: ZEND_ASSERT(0 /* not supported */); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 7e5ec69a39d48..52678aec1c6e5 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1798,7 +1798,7 @@ ZEND_VM_C_LABEL(fetch_this): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR, CONST, CACHE_SLOT) +ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_SLOT) { USE_OPLINE SAVE_OPLINE(); @@ -1813,6 +1813,42 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR, CONST, CACHE_SLOT) zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_P(outer_class_zv)); HANDLE_EXCEPTION(); } + } else if (OP1_TYPE == IS_UNUSED) { + uint32_t fetch_type; + zend_class_entry *called_scope, *scope; + + fetch_type = opline->op1.num; + scope = EX(func)->op_array.scope; + if (UNEXPECTED(scope == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", + fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : + fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + if (fetch_type & ZEND_FETCH_CLASS_SELF) { + outer_ce = scope; + } else if (fetch_type & ZEND_FETCH_CLASS_PARENT) { + if (UNEXPECTED(scope->parent == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, + "Cannot use \"parent\" when current class scope has no parent"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + outer_ce = scope->parent; + } else if (fetch_type & ZEND_FETCH_CLASS_STATIC) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + called_scope = Z_OBJCE(EX(This)); + } else { + called_scope = Z_CE(EX(This)); + } + outer_ce = called_scope; + } else { + zend_throw_error(NULL, "Unknown scope resolution"); + HANDLE_EXCEPTION(); + } } else { outer_ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(outer_ce == NULL)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 36ae015622552..3b407d62c7bba 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6625,6 +6625,42 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_P(outer_class_zv)); HANDLE_EXCEPTION(); } + } else if (IS_CONST == IS_UNUSED) { + uint32_t fetch_type; + zend_class_entry *called_scope, *scope; + + fetch_type = opline->op1.num; + scope = EX(func)->op_array.scope; + if (UNEXPECTED(scope == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", + fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : + fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + if (fetch_type & ZEND_FETCH_CLASS_SELF) { + outer_ce = scope; + } else if (fetch_type & ZEND_FETCH_CLASS_PARENT) { + if (UNEXPECTED(scope->parent == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, + "Cannot use \"parent\" when current class scope has no parent"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + outer_ce = scope->parent; + } else if (fetch_type & ZEND_FETCH_CLASS_STATIC) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + called_scope = Z_OBJCE(EX(This)); + } else { + called_scope = Z_CE(EX(This)); + } + outer_ce = called_scope; + } else { + zend_throw_error(NULL, "Unknown scope resolution"); + HANDLE_EXCEPTION(); + } } else { outer_ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(outer_ce == NULL)) { @@ -16185,6 +16221,42 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_P(outer_class_zv)); HANDLE_EXCEPTION(); } + } else if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + uint32_t fetch_type; + zend_class_entry *called_scope, *scope; + + fetch_type = opline->op1.num; + scope = EX(func)->op_array.scope; + if (UNEXPECTED(scope == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", + fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : + fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + if (fetch_type & ZEND_FETCH_CLASS_SELF) { + outer_ce = scope; + } else if (fetch_type & ZEND_FETCH_CLASS_PARENT) { + if (UNEXPECTED(scope->parent == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, + "Cannot use \"parent\" when current class scope has no parent"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + outer_ce = scope->parent; + } else if (fetch_type & ZEND_FETCH_CLASS_STATIC) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + called_scope = Z_OBJCE(EX(This)); + } else { + called_scope = Z_CE(EX(This)); + } + outer_ce = called_scope; + } else { + zend_throw_error(NULL, "Unknown scope resolution"); + HANDLE_EXCEPTION(); + } } else { outer_ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(outer_ce == NULL)) { @@ -33830,6 +33902,85 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + SAVE_OPLINE(); + + zend_string *inner_class_name, *full_class_name; + zend_class_entry *outer_ce = NULL, *inner_ce = NULL; + + if (IS_UNUSED == IS_CONST) { + zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); + outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv)); + if (!outer_ce) { + zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_P(outer_class_zv)); + HANDLE_EXCEPTION(); + } + } else if (IS_UNUSED == IS_UNUSED) { + uint32_t fetch_type; + zend_class_entry *called_scope, *scope; + + fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK; + scope = EX(func)->op_array.scope; + if (UNEXPECTED(scope == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", + fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : + fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + if (fetch_type == ZEND_FETCH_CLASS_SELF) { + outer_ce = scope; + } else if (fetch_type == ZEND_FETCH_CLASS_PARENT) { + if (UNEXPECTED(scope->parent == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, + "Cannot use \"parent\" when current class scope has no parent"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + outer_ce = scope->parent; + } else if (fetch_type == ZEND_FETCH_CLASS_STATIC) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + called_scope = Z_OBJCE(EX(This)); + } else { + called_scope = Z_CE(EX(This)); + } + outer_ce = called_scope; + } else { + zend_throw_error(NULL, "Unknown scope resolution"); + HANDLE_EXCEPTION(); + } + } else { + outer_ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(outer_ce == NULL)) { + outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + } + + inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + + full_class_name = zend_string_concat3( + ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name), + ":>", 2, + ZSTR_VAL(inner_class_name), ZSTR_LEN(inner_class_name) + ); + + inner_ce = zend_lookup_class(full_class_name); + if (!inner_ce) { + zend_error(E_ERROR, "Class '%s' not found", ZSTR_VAL(full_class_name)); + } + + CACHE_PTR(opline->extended_value, inner_ce); + Z_CE_P(EX_VAR(opline->result.var)) = inner_ce; + + zend_string_release(full_class_name); + + ZEND_VM_NEXT_OPCODE(); +} + static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -57732,7 +57883,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_LABEL, (void*)&&ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_FCALL_OFFSET_SPEC_CONST_LABEL, (void*)&&ZEND_RECV_NOTYPE_SPEC_LABEL, @@ -62473,6 +62624,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST): + VM_TRACE(ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST) + ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST) + HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST): VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST) ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -66934,7 +67090,7 @@ void zend_vm_init(void) ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_HANDLER, ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER, ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, + ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST_HANDLER, ZEND_NULL_HANDLER, ZEND_INIT_FCALL_OFFSET_SPEC_CONST_HANDLER, ZEND_RECV_NOTYPE_SPEC_HANDLER, @@ -68585,4 +68741,3 @@ ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data* ex) #endif return ret; } - diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index 3bf5234bf696d..e632a82498637 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -1375,6 +1375,7 @@ _(2577, ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST) \ _(2578, ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST) \ _(2579, ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST) \ + _(2580, ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST) \ _(2582, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ _(2583, ZEND_RECV_NOTYPE_SPEC) \ _(2585, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ diff --git a/tests/classes/inner_classes_012.phpt b/tests/classes/inner_classes_012.phpt new file mode 100644 index 0000000000000..54611341343e6 --- /dev/null +++ b/tests/classes/inner_classes_012.phpt @@ -0,0 +1,43 @@ +--TEST-- +scope resolution access +--FILE-- +Middle { + return new static:>Middle(); + } + public static function testSelf(): self:>Middle { + return new self:>Middle(); + } +} + +class Outer2 extends Outer { + public class Middle extends parent:>Middle { + } + + public static function testParent(): parent:>Middle { + return new parent:>Middle(); + } +} + +var_dump(Outer::testStatic()); +var_dump(Outer::testSelf()); +var_dump(Outer2::testParent()); +var_dump(Outer2::testStatic()); +var_dump(Outer2::testSelf()); + +?> +--EXPECT-- +object(Outer:>Middle)#1 (0) { +} +object(Outer:>Middle)#1 (0) { +} +object(Outer:>Middle)#1 (0) { +} +object(Outer2:>Middle)#1 (0) { +} +object(Outer:>Middle)#1 (0) { +} From 05225e3a2f2e41b162c344be507acfaf5186af63 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sun, 9 Mar 2025 18:35:20 +0100 Subject: [PATCH 12/65] update reflection --- ext/reflection/php_reflection.c | 50 +++++++++++++++++++++++++ ext/reflection/php_reflection.stub.php | 8 ++++ ext/reflection/php_reflection_arginfo.h | 18 ++++++++- tests/classes/inner_classes_013.phpt | 31 +++++++++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 tests/classes/inner_classes_013.phpt diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index bc8ffbdd8bd8e..c297426c06d9a 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4075,6 +4075,56 @@ static void add_class_vars(zend_class_entry *ce, bool statics, zval *return_valu } /* }}} */ +/* {{{ Returns whether the current class is an inner class */ +ZEND_METHOD(ReflectionClass, isInnerClass) +{ + reflection_object *intern; + zend_class_entry *ce; + + ZEND_PARSE_PARAMETERS_NONE(); + + GET_REFLECTION_OBJECT_PTR(ce); + + // If the class is an inner class, it will have a T_INNER_REF in its name + // todo: make this better? + + RETURN_BOOL(strstr(ZSTR_VAL(ce->name), ":>") != NULL); +} +/* }}} */ + +/* {{{ Returns true if the class is private */ +ZEND_METHOD(ReflectionClass, isPrivate) +{ + reflection_object *intern; + zend_class_entry *ce; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(ce); + RETURN_BOOL(ce->required_scope && ce->required_scope_absolute); +} + +/* {{{ Returns true if the class is protected */ +ZEND_METHOD(ReflectionClass, isProtected) +{ + reflection_object *intern; + zend_class_entry *ce; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(ce); + RETURN_BOOL(ce->required_scope && !ce->required_scope_absolute); +} + +/* {{{ Returns true if the class is public */ +ZEND_METHOD(ReflectionClass, isPublic) +{ + reflection_object *intern; + zend_class_entry *ce; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(ce); + RETURN_BOOL(!ce->required_scope); +} + /* {{{ Returns an associative array containing all static property values of the class */ ZEND_METHOD(ReflectionClass, getStaticProperties) { diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index be511d7ee14cd..6b03c6deb03c8 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -432,6 +432,14 @@ public function getNamespaceName(): string {} public function getShortName(): string {} public function getAttributes(?string $name = null, int $flags = 0): array {} + + public function isInnerClass(): bool {} + + public function isPrivate(): bool {} + + public function isProtected(): bool {} + + public function isPublic(): bool {} } class ReflectionObject extends ReflectionClass diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index d78a685dde9c9..9630754e93c27 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: 3c6be99bb36965139464925a618cb0bf03affa62 */ + * Stub hash: be0cae939aa05863ce2206767bbb923ea9951dd7 */ 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) @@ -366,6 +366,14 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionClass_getAttributes arginfo_class_ReflectionFunctionAbstract_getAttributes +#define arginfo_class_ReflectionClass_isInnerClass arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + +#define arginfo_class_ReflectionClass_isPrivate arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + +#define arginfo_class_ReflectionClass_isProtected arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + +#define arginfo_class_ReflectionClass_isPublic arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionObject___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) ZEND_END_ARG_INFO() @@ -847,6 +855,10 @@ ZEND_METHOD(ReflectionClass, inNamespace); ZEND_METHOD(ReflectionClass, getNamespaceName); ZEND_METHOD(ReflectionClass, getShortName); ZEND_METHOD(ReflectionClass, getAttributes); +ZEND_METHOD(ReflectionClass, isInnerClass); +ZEND_METHOD(ReflectionClass, isPrivate); +ZEND_METHOD(ReflectionClass, isProtected); +ZEND_METHOD(ReflectionClass, isPublic); ZEND_METHOD(ReflectionObject, __construct); ZEND_METHOD(ReflectionProperty, __construct); ZEND_METHOD(ReflectionProperty, __toString); @@ -1139,6 +1151,10 @@ static const zend_function_entry class_ReflectionClass_methods[] = { ZEND_ME(ReflectionClass, getNamespaceName, arginfo_class_ReflectionClass_getNamespaceName, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, getShortName, arginfo_class_ReflectionClass_getShortName, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, getAttributes, arginfo_class_ReflectionClass_getAttributes, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, isInnerClass, arginfo_class_ReflectionClass_isInnerClass, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, isPrivate, arginfo_class_ReflectionClass_isPrivate, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, isProtected, arginfo_class_ReflectionClass_isProtected, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, isPublic, arginfo_class_ReflectionClass_isPublic, ZEND_ACC_PUBLIC) ZEND_FE_END }; diff --git a/tests/classes/inner_classes_013.phpt b/tests/classes/inner_classes_013.phpt new file mode 100644 index 0000000000000..0f1f53bae838e --- /dev/null +++ b/tests/classes/inner_classes_013.phpt @@ -0,0 +1,31 @@ +--TEST-- +reflection on inner classes +--FILE-- +Middle:>Inner'); +var_dump($ref->getName()); +var_dump($ref->getShortName()); +var_dump($ref->isInnerClass()); +var_dump($outer->isInnerClass()); +var_dump($ref->isPrivate()); +var_dump($ref->isProtected()); +var_dump($ref->isPublic()); +?> +--EXPECT-- +string(24) "n\s\Outer:>Middle:>Inner" +string(20) "Outer:>Middle:>Inner" +bool(true) +bool(false) +bool(false) +bool(false) +bool(true) From 6e8031cf9ec15b16fedbde5afcad24653b77decc Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sun, 9 Mar 2025 19:32:47 +0100 Subject: [PATCH 13/65] enable visibility --- Zend/zend_execute.c | 17 +++++++ Zend/zend_vm_def.h | 26 +++++++--- Zend/zend_vm_execute.h | 71 +++++++++++++++++++++------- tests/classes/inner_classes_014.phpt | 28 +++++++++++ tests/classes/inner_classes_015.phpt | 31 ++++++++++++ tests/classes/inner_classes_016.phpt | 25 ++++++++++ tests/classes/inner_classes_017.phpt | 25 ++++++++++ 7 files changed, 199 insertions(+), 24 deletions(-) create mode 100644 tests/classes/inner_classes_014.phpt create mode 100644 tests/classes/inner_classes_015.phpt create mode 100644 tests/classes/inner_classes_016.phpt create mode 100644 tests/classes/inner_classes_017.phpt diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 6b6af2c225f79..efa759f334ef8 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1196,6 +1196,23 @@ static zend_always_inline bool zend_check_type_slow( } } else { ce = zend_fetch_ce_from_cache_slot(cache_slot, type); + + // verify that the class is being used in the correct scope + if (ce && ce->required_scope) { + zend_class_entry *scope = zend_get_executed_scope(); + if (ce->required_scope_absolute && scope != ce->required_scope) { + if (scope == NULL) { + zend_error(E_ERROR, "Private inner class %s cannot be used as a type declaration in the global scope", ce->name->val); + } + + zend_error(E_ERROR, "Private inner class %s cannot be used as a type declaration in the scope of %s", ce->name->val, scope->name->val); + } else if (scope == NULL) { + zend_error(E_ERROR, "Protected inner class %s cannot be used as a type declaration in the global scope", ce->name->val); + } else if (!instanceof_function(scope, ce->required_scope)) { + zend_error(E_ERROR, "Protected inner class %s cannot be used as a type declaration in the scope of %s", ce->name->val, scope->name->val); + } + } + /* If we have a CE we check if it satisfies the type constraint, * otherwise it will check if a standard type satisfies it. */ if (ce && instanceof_function(Z_OBJCE_P(arg), ce)) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 52678aec1c6e5..98222a50e4725 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1804,7 +1804,9 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S SAVE_OPLINE(); zend_string *inner_class_name, *full_class_name; - zend_class_entry *outer_ce = NULL, *inner_ce = NULL; + zend_class_entry *outer_ce = NULL, *inner_ce = NULL, *scope = NULL; + + scope = EX(func)->op_array.scope; if (OP1_TYPE == IS_CONST) { zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); @@ -1815,10 +1817,9 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S } } else if (OP1_TYPE == IS_UNUSED) { uint32_t fetch_type; - zend_class_entry *called_scope, *scope; + zend_class_entry *called_scope; - fetch_type = opline->op1.num; - scope = EX(func)->op_array.scope; + fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK; if (UNEXPECTED(scope == NULL)) { SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", @@ -1827,9 +1828,9 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - if (fetch_type & ZEND_FETCH_CLASS_SELF) { + if (fetch_type == ZEND_FETCH_CLASS_SELF) { outer_ce = scope; - } else if (fetch_type & ZEND_FETCH_CLASS_PARENT) { + } else if (fetch_type == ZEND_FETCH_CLASS_PARENT) { if (UNEXPECTED(scope->parent == NULL)) { SAVE_OPLINE(); zend_throw_error(NULL, @@ -1838,7 +1839,7 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S HANDLE_EXCEPTION(); } outer_ce = scope->parent; - } else if (fetch_type & ZEND_FETCH_CLASS_STATIC) { + } else if (fetch_type == ZEND_FETCH_CLASS_STATIC) { if (Z_TYPE(EX(This)) == IS_OBJECT) { called_scope = Z_OBJCE(EX(This)); } else { @@ -1867,6 +1868,17 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S inner_ce = zend_lookup_class(full_class_name); if (!inner_ce) { zend_error(E_ERROR, "Class '%s' not found", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } + + if (inner_ce->required_scope) { + if (inner_ce->required_scope_absolute && inner_ce->required_scope != scope) { + zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } else if (scope == NULL || !instanceof_function(scope, inner_ce->required_scope)) { + zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } } CACHE_PTR(opline->extended_value, inner_ce); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 3b407d62c7bba..0ffc1de667925 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6616,7 +6616,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C SAVE_OPLINE(); zend_string *inner_class_name, *full_class_name; - zend_class_entry *outer_ce = NULL, *inner_ce = NULL; + zend_class_entry *outer_ce = NULL, *inner_ce = NULL, *scope = NULL; + + scope = EX(func)->op_array.scope; if (IS_CONST == IS_CONST) { zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); @@ -6627,10 +6629,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C } } else if (IS_CONST == IS_UNUSED) { uint32_t fetch_type; - zend_class_entry *called_scope, *scope; + zend_class_entry *called_scope; - fetch_type = opline->op1.num; - scope = EX(func)->op_array.scope; + fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK; if (UNEXPECTED(scope == NULL)) { SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", @@ -6639,9 +6640,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - if (fetch_type & ZEND_FETCH_CLASS_SELF) { + if (fetch_type == ZEND_FETCH_CLASS_SELF) { outer_ce = scope; - } else if (fetch_type & ZEND_FETCH_CLASS_PARENT) { + } else if (fetch_type == ZEND_FETCH_CLASS_PARENT) { if (UNEXPECTED(scope->parent == NULL)) { SAVE_OPLINE(); zend_throw_error(NULL, @@ -6650,7 +6651,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C HANDLE_EXCEPTION(); } outer_ce = scope->parent; - } else if (fetch_type & ZEND_FETCH_CLASS_STATIC) { + } else if (fetch_type == ZEND_FETCH_CLASS_STATIC) { if (Z_TYPE(EX(This)) == IS_OBJECT) { called_scope = Z_OBJCE(EX(This)); } else { @@ -6679,6 +6680,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C inner_ce = zend_lookup_class(full_class_name); if (!inner_ce) { zend_error(E_ERROR, "Class '%s' not found", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } + + if (inner_ce->required_scope) { + if (inner_ce->required_scope_absolute && inner_ce->required_scope != scope) { + zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } else if (scope == NULL || !instanceof_function(scope, inner_ce->required_scope)) { + zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } } CACHE_PTR(opline->extended_value, inner_ce); @@ -16212,7 +16224,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ SAVE_OPLINE(); zend_string *inner_class_name, *full_class_name; - zend_class_entry *outer_ce = NULL, *inner_ce = NULL; + zend_class_entry *outer_ce = NULL, *inner_ce = NULL, *scope = NULL; + + scope = EX(func)->op_array.scope; if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); @@ -16223,10 +16237,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ } } else if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { uint32_t fetch_type; - zend_class_entry *called_scope, *scope; + zend_class_entry *called_scope; - fetch_type = opline->op1.num; - scope = EX(func)->op_array.scope; + fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK; if (UNEXPECTED(scope == NULL)) { SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", @@ -16235,9 +16248,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - if (fetch_type & ZEND_FETCH_CLASS_SELF) { + if (fetch_type == ZEND_FETCH_CLASS_SELF) { outer_ce = scope; - } else if (fetch_type & ZEND_FETCH_CLASS_PARENT) { + } else if (fetch_type == ZEND_FETCH_CLASS_PARENT) { if (UNEXPECTED(scope->parent == NULL)) { SAVE_OPLINE(); zend_throw_error(NULL, @@ -16246,7 +16259,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ HANDLE_EXCEPTION(); } outer_ce = scope->parent; - } else if (fetch_type & ZEND_FETCH_CLASS_STATIC) { + } else if (fetch_type == ZEND_FETCH_CLASS_STATIC) { if (Z_TYPE(EX(This)) == IS_OBJECT) { called_scope = Z_OBJCE(EX(This)); } else { @@ -16275,6 +16288,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ inner_ce = zend_lookup_class(full_class_name); if (!inner_ce) { zend_error(E_ERROR, "Class '%s' not found", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } + + if (inner_ce->required_scope) { + if (inner_ce->required_scope_absolute && inner_ce->required_scope != scope) { + zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } else if (scope == NULL || !instanceof_function(scope, inner_ce->required_scope)) { + zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } } CACHE_PTR(opline->extended_value, inner_ce); @@ -33908,7 +33932,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_ SAVE_OPLINE(); zend_string *inner_class_name, *full_class_name; - zend_class_entry *outer_ce = NULL, *inner_ce = NULL; + zend_class_entry *outer_ce = NULL, *inner_ce = NULL, *scope = NULL; + + scope = EX(func)->op_array.scope; if (IS_UNUSED == IS_CONST) { zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); @@ -33919,10 +33945,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_ } } else if (IS_UNUSED == IS_UNUSED) { uint32_t fetch_type; - zend_class_entry *called_scope, *scope; + zend_class_entry *called_scope; fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK; - scope = EX(func)->op_array.scope; if (UNEXPECTED(scope == NULL)) { SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", @@ -33971,6 +33996,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_ inner_ce = zend_lookup_class(full_class_name); if (!inner_ce) { zend_error(E_ERROR, "Class '%s' not found", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } + + if (inner_ce->required_scope) { + if (inner_ce->required_scope_absolute && inner_ce->required_scope != scope) { + zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } else if (scope == NULL || !instanceof_function(scope, inner_ce->required_scope)) { + zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } } CACHE_PTR(opline->extended_value, inner_ce); @@ -68741,3 +68777,4 @@ ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data* ex) #endif return ret; } + diff --git a/tests/classes/inner_classes_014.phpt b/tests/classes/inner_classes_014.phpt new file mode 100644 index 0000000000000..69075dbb5fe01 --- /dev/null +++ b/tests/classes/inner_classes_014.phpt @@ -0,0 +1,28 @@ +--TEST-- +private inner class +--FILE-- +Inner { + return new self:>Inner(); + } +} + +class Foo extends Outer { + public function getInner(): parent:>Inner { + var_dump(parent::getInner()); + return new parent:>Inner(); + } +} + +$outer = new Foo(); +var_dump($outer->getInner()); +?> +--EXPECTF-- +object(Outer:>Inner)#2 (0) { +} + +Fatal error: Class 'Outer:>Inner' is private in %s on line %d diff --git a/tests/classes/inner_classes_015.phpt b/tests/classes/inner_classes_015.phpt new file mode 100644 index 0000000000000..a13dc62da3b32 --- /dev/null +++ b/tests/classes/inner_classes_015.phpt @@ -0,0 +1,31 @@ +--TEST-- +protected inner class +--FILE-- +Inner { + return new self:>Inner(); + } +} + +class Foo extends Outer { + public function getInner(): parent:>Inner { + var_dump(parent::getInner()); + return new parent:>Inner(); + } +} + +$outer = new Foo(); +var_dump($outer->getInner()); +var_dump(new Outer:>Inner()); +?> +--EXPECTF-- +object(Outer:>Inner)#2 (0) { +} +object(Outer:>Inner)#2 (0) { +} + +Fatal error: Class 'Outer:>Inner' is protected in %s on line %d diff --git a/tests/classes/inner_classes_016.phpt b/tests/classes/inner_classes_016.phpt new file mode 100644 index 0000000000000..2a068e5e18f66 --- /dev/null +++ b/tests/classes/inner_classes_016.phpt @@ -0,0 +1,25 @@ +--TEST-- +private return types +--FILE-- +Inner { + return new self:>Inner(); + } +} + +$r = Outer::getInner(); +function test($r): Outer:>Inner { + return $r; +} +var_dump($r); +test($r); +?> +--EXPECTF-- +object(Outer:>Inner)#1 (0) { +} + +Fatal error: Private inner class Outer:>Inner cannot be used as a type declaration in the global scope in %s on line %d diff --git a/tests/classes/inner_classes_017.phpt b/tests/classes/inner_classes_017.phpt new file mode 100644 index 0000000000000..3ae34f33c852c --- /dev/null +++ b/tests/classes/inner_classes_017.phpt @@ -0,0 +1,25 @@ +--TEST-- +protected return types +--FILE-- +Inner { + return new self:>Inner(); + } +} + +$r = Outer::getInner(); +function test($r): Outer:>Inner { + return $r; +} +var_dump($r); +test($r); +?> +--EXPECTF-- +object(Outer:>Inner)#1 (0) { +} + +Fatal error: Protected inner class Outer:>Inner cannot be used as a type declaration in the global scope in %s on line %d From d4a4d32e6d71505ca6e9f67824a4ff9abb90679d Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sun, 9 Mar 2025 19:49:08 +0100 Subject: [PATCH 14/65] add tests for autoloading --- Zend/zend_compile.c | 3 --- tests/classes/inner_classes.inc | 9 +++++++++ tests/classes/inner_classes_019.phpt | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 tests/classes/inner_classes.inc create mode 100644 tests/classes/inner_classes_019.phpt diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 203cf34f03444..56a87f110108b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -9205,9 +9205,6 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) // if a class is private or protected, we need to require the correct scope ce->required_scope = propFlags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED) ? CG(active_class_entry) : NULL; ce->required_scope_absolute = propFlags & ZEND_ACC_PRIVATE ? true : false; - if (ce->required_scope) { - ce->required_scope->refcount ++; - } // ensure the class is treated as a top-level class and not an anon class toplevel = true; diff --git a/tests/classes/inner_classes.inc b/tests/classes/inner_classes.inc new file mode 100644 index 0000000000000..793804cf6606e --- /dev/null +++ b/tests/classes/inner_classes.inc @@ -0,0 +1,9 @@ +Line(); +var_dump($line); +?> +--EXPECTF-- +autoload(inner_classes) + +Fatal error: Class 'inner_classes:>Line' is private in %s on line %d From b42316ccfebea0de53b26de464c9e6cf169a51e2 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sun, 9 Mar 2025 20:17:59 +0100 Subject: [PATCH 15/65] properly persist classes in opcache --- ext/opcache/zend_persist.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 3d45c63a98781..fa82f997ee3a5 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -1121,6 +1121,18 @@ zend_class_entry *zend_persist_class_entry(zend_class_entry *orig_ce) return ce; } +void zend_update_required_scope(zend_class_entry *ce) +{ + if (ce->required_scope) { + zend_class_entry *required_scope = ce->required_scope; + + zend_class_entry *r = zend_shared_alloc_get_xlat_entry(required_scope); + if (r) { + ce->required_scope = r; + } + } +} + void zend_update_parent_ce(zend_class_entry *ce) { if (ce->ce_flags & ZEND_ACC_LINKED) { @@ -1294,6 +1306,7 @@ static void zend_accel_persist_class_table(HashTable *class_table) if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) { ce = Z_PTR(p->val); zend_update_parent_ce(ce); + zend_update_required_scope(ce); } } ZEND_HASH_FOREACH_END(); #ifdef HAVE_JIT From cbd51f7f6ebd9f6ca6f1c4ce8f8f299aa4d093b6 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sun, 9 Mar 2025 23:26:42 +0100 Subject: [PATCH 16/65] handle return type visibility enforcement --- Zend/zend_vm_def.h | 24 ++++- Zend/zend_vm_execute.h | 154 ++++++++++++++++----------- tests/classes/inner_classes_014.phpt | 8 +- tests/classes/inner_classes_015.phpt | 10 +- tests/classes/inner_classes_016.phpt | 9 +- tests/classes/inner_classes_017.phpt | 9 +- 6 files changed, 136 insertions(+), 78 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 98222a50e4725..2d13f49a70cb1 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1851,10 +1851,7 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S HANDLE_EXCEPTION(); } } else { - outer_ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(outer_ce == NULL)) { - outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); - } + outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); } inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); @@ -4518,6 +4515,24 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV } SAVE_OPLINE(); + + if (Z_OBJCE_P(retval_ptr)->required_scope) { + if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { + if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { + zend_type_error("Method %s is public but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } else { + zend_type_error("Method %s is public but returns a protected class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } + } else if (EX(func)->common.fn_flags & ZEND_ACC_PROTECTED) { + if (Z_OBJCE_P(retval_ptr)->required_scope_absolute && Z_OBJCE_P(retval_ptr)->required_scope != EX(func)->common.scope) { + zend_type_error("Method %s is protected but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } + } + } + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, cache_slot, 1, 0))) { zend_verify_return_error(EX(func), retval_ptr); HANDLE_EXCEPTION(); @@ -8264,6 +8279,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) case ZEND_FETCH_CLASS: case ZEND_DECLARE_ANON_CLASS: + case ZEND_FETCH_INNER_CLASS: break; /* return value is zend_class_entry pointer */ default: diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 0ffc1de667925..cde630e1ab345 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3310,6 +3310,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER( case ZEND_FETCH_CLASS: case ZEND_DECLARE_ANON_CLASS: + case ZEND_FETCH_INNER_CLASS: break; /* return value is zend_class_entry pointer */ default: @@ -6663,10 +6664,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C HANDLE_EXCEPTION(); } } else { - outer_ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(outer_ce == NULL)) { - outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); - } + outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); } inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); @@ -7404,10 +7402,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C IS_CONST == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ - } else if (IS_CONST != IS_CONST && - IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { @@ -9978,10 +9972,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C (IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ - } else if (IS_CONST != IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -10736,10 +10726,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C IS_UNUSED == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ - } else if (IS_CONST != IS_CONST && - IS_UNUSED == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { function_name = NULL; if (IS_UNUSED != IS_CONST) { @@ -10890,6 +10876,24 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP } SAVE_OPLINE(); + + if (Z_OBJCE_P(retval_ptr)->required_scope) { + if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { + if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { + zend_type_error("Method %s is public but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } else { + zend_type_error("Method %s is public but returns a protected class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } + } else if (EX(func)->common.fn_flags & ZEND_ACC_PROTECTED) { + if (Z_OBJCE_P(retval_ptr)->required_scope_absolute && Z_OBJCE_P(retval_ptr)->required_scope != EX(func)->common.scope) { + zend_type_error("Method %s is protected but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } + } + } + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, cache_slot, 1, 0))) { zend_verify_return_error(EX(func), retval_ptr); HANDLE_EXCEPTION(); @@ -12470,10 +12474,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C IS_CV == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ - } else if (IS_CONST != IS_CONST && - IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { function_name = EX_VAR(opline->op2.var); if (IS_CV != IS_CONST) { @@ -16271,10 +16271,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ HANDLE_EXCEPTION(); } } else { - outer_ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(outer_ce == NULL)) { - outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); - } + outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); } inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); @@ -21718,6 +21715,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN } SAVE_OPLINE(); + + if (Z_OBJCE_P(retval_ptr)->required_scope) { + if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { + if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { + zend_type_error("Method %s is public but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } else { + zend_type_error("Method %s is public but returns a protected class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } + } else if (EX(func)->common.fn_flags & ZEND_ACC_PROTECTED) { + if (Z_OBJCE_P(retval_ptr)->required_scope_absolute && Z_OBJCE_P(retval_ptr)->required_scope != EX(func)->common.scope) { + zend_type_error("Method %s is protected but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } + } + } + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, cache_slot, 1, 0))) { zend_verify_return_error(EX(func), retval_ptr); HANDLE_EXCEPTION(); @@ -25597,10 +25612,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V IS_CONST == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ - } else if (IS_VAR != IS_CONST && - IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { @@ -28530,10 +28541,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V (IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ - } else if (IS_VAR != IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -30040,10 +30047,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V IS_UNUSED == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ - } else if (IS_VAR != IS_CONST && - IS_UNUSED == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { function_name = NULL; if (IS_UNUSED != IS_CONST) { @@ -30194,6 +30197,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN } SAVE_OPLINE(); + + if (Z_OBJCE_P(retval_ptr)->required_scope) { + if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { + if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { + zend_type_error("Method %s is public but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } else { + zend_type_error("Method %s is public but returns a protected class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } + } else if (EX(func)->common.fn_flags & ZEND_ACC_PROTECTED) { + if (Z_OBJCE_P(retval_ptr)->required_scope_absolute && Z_OBJCE_P(retval_ptr)->required_scope != EX(func)->common.scope) { + zend_type_error("Method %s is protected but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } + } + } + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, cache_slot, 1, 0))) { zend_verify_return_error(EX(func), retval_ptr); HANDLE_EXCEPTION(); @@ -32979,10 +33000,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V IS_CV == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ - } else if (IS_VAR != IS_CONST && - IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { function_name = EX_VAR(opline->op2.var); if (IS_CV != IS_CONST) { @@ -33979,10 +33996,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_ HANDLE_EXCEPTION(); } } else { - outer_ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(outer_ce == NULL)) { - outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); - } + outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); } inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); @@ -35341,10 +35355,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U IS_CONST == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ - } else if (IS_UNUSED != IS_CONST && - IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { @@ -37510,10 +37520,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U (IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ - } else if (IS_UNUSED != IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -37921,10 +37927,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U IS_UNUSED == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ - } else if (IS_UNUSED != IS_CONST && - IS_UNUSED == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { function_name = NULL; if (IS_UNUSED != IS_CONST) { @@ -38075,6 +38077,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED } SAVE_OPLINE(); + + if (Z_OBJCE_P(retval_ptr)->required_scope) { + if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { + if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { + zend_type_error("Method %s is public but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } else { + zend_type_error("Method %s is public but returns a protected class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } + } else if (EX(func)->common.fn_flags & ZEND_ACC_PROTECTED) { + if (Z_OBJCE_P(retval_ptr)->required_scope_absolute && Z_OBJCE_P(retval_ptr)->required_scope != EX(func)->common.scope) { + zend_type_error("Method %s is protected but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } + } + } + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, cache_slot, 1, 0))) { zend_verify_return_error(EX(func), retval_ptr); HANDLE_EXCEPTION(); @@ -40155,10 +40175,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U IS_CV == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ - } else if (IS_UNUSED != IS_CONST && - IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { function_name = EX_VAR(opline->op2.var); if (IS_CV != IS_CONST) { @@ -50876,6 +50892,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU } SAVE_OPLINE(); + + if (Z_OBJCE_P(retval_ptr)->required_scope) { + if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { + if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { + zend_type_error("Method %s is public but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } else { + zend_type_error("Method %s is public but returns a protected class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } + } else if (EX(func)->common.fn_flags & ZEND_ACC_PROTECTED) { + if (Z_OBJCE_P(retval_ptr)->required_scope_absolute && Z_OBJCE_P(retval_ptr)->required_scope != EX(func)->common.scope) { + zend_type_error("Method %s is protected but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + HANDLE_EXCEPTION(); + } + } + } + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, cache_slot, 1, 0))) { zend_verify_return_error(EX(func), retval_ptr); HANDLE_EXCEPTION(); diff --git a/tests/classes/inner_classes_014.phpt b/tests/classes/inner_classes_014.phpt index 69075dbb5fe01..80aab3c3e68b2 100644 --- a/tests/classes/inner_classes_014.phpt +++ b/tests/classes/inner_classes_014.phpt @@ -6,14 +6,18 @@ private inner class class Outer { private class Inner {} - public function getInner(): self:>Inner { + private function getInner(): self:>Inner { return new self:>Inner(); } + + public function getInner2(): mixed { + return $this->getInner(); + } } class Foo extends Outer { public function getInner(): parent:>Inner { - var_dump(parent::getInner()); + var_dump(parent::getInner2()); return new parent:>Inner(); } } diff --git a/tests/classes/inner_classes_015.phpt b/tests/classes/inner_classes_015.phpt index a13dc62da3b32..e96529b108d0d 100644 --- a/tests/classes/inner_classes_015.phpt +++ b/tests/classes/inner_classes_015.phpt @@ -6,7 +6,7 @@ protected inner class class Outer { protected class Inner {} - public function getInner(): self:>Inner { + protected function getInner(): self:>Inner { return new self:>Inner(); } } @@ -25,7 +25,9 @@ var_dump(new Outer:>Inner()); --EXPECTF-- object(Outer:>Inner)#2 (0) { } -object(Outer:>Inner)#2 (0) { -} -Fatal error: Class 'Outer:>Inner' is protected in %s on line %d +Fatal error: Uncaught TypeError: Method getInner is public but returns a protected class: Outer:>Inner in %s:%d +Stack trace: +#0 %s(%d): Foo->getInner() +#1 {main} + thrown in %s on line %d diff --git a/tests/classes/inner_classes_016.phpt b/tests/classes/inner_classes_016.phpt index 2a068e5e18f66..efc50b6bca1d5 100644 --- a/tests/classes/inner_classes_016.phpt +++ b/tests/classes/inner_classes_016.phpt @@ -19,7 +19,8 @@ var_dump($r); test($r); ?> --EXPECTF-- -object(Outer:>Inner)#1 (0) { -} - -Fatal error: Private inner class Outer:>Inner cannot be used as a type declaration in the global scope in %s on line %d +Fatal error: Uncaught TypeError: Method getInner is public but returns a private class: Outer:>Inner in %s:%d +Stack trace: +#0 %s(%d): Outer::getInner() +#1 {main} + thrown in %s on line %d diff --git a/tests/classes/inner_classes_017.phpt b/tests/classes/inner_classes_017.phpt index 3ae34f33c852c..4e804831479a3 100644 --- a/tests/classes/inner_classes_017.phpt +++ b/tests/classes/inner_classes_017.phpt @@ -19,7 +19,8 @@ var_dump($r); test($r); ?> --EXPECTF-- -object(Outer:>Inner)#1 (0) { -} - -Fatal error: Protected inner class Outer:>Inner cannot be used as a type declaration in the global scope in %s on line %d +Fatal error: Uncaught TypeError: Method getInner is public but returns a protected class: Outer:>Inner in %s:%d +Stack trace: +#0 %s(%d): Outer::getInner() +#1 {main} + thrown in %s on line %d From a86c26e37a022930e5aefca40fc37f363749fb12 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 11 Mar 2025 08:12:59 +0100 Subject: [PATCH 17/65] fix static member access --- Zend/zend_compile.c | 3 ++- tests/classes/inner_classes_018.phpt | 15 +++++++++++++++ tests/classes/inner_classes_020.phpt | 23 +++++++++++++++++++++++ tests/classes/inner_classes_021.phpt | 1 + 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 tests/classes/inner_classes_018.phpt create mode 100644 tests/classes/inner_classes_020.phpt create mode 100644 tests/classes/inner_classes_021.phpt diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 56a87f110108b..59eae8fb17dc0 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2943,7 +2943,8 @@ static void zend_compile_inner_class_ref(znode *result, zend_ast *ast, uint32_t } zend_op *opline = zend_emit_op(result, ZEND_FETCH_INNER_CLASS, &outer_node, &inner_node); - opline->extended_value = zend_alloc_cache_slot(); + // ensure we allocate two slots to prevent an issue with static method access + opline->extended_value = zend_alloc_cache_slots(2); } /* }}} */ diff --git a/tests/classes/inner_classes_018.phpt b/tests/classes/inner_classes_018.phpt new file mode 100644 index 0000000000000..eef4cdfa5de09 --- /dev/null +++ b/tests/classes/inner_classes_018.phpt @@ -0,0 +1,15 @@ +--TEST-- +ensure autoloading works +--FILE-- +Point(1, 2); +echo $point->x, ' ', $point->y, "\n"; +?> +--EXPECT-- +autoload(inner_classes) +1 2 diff --git a/tests/classes/inner_classes_020.phpt b/tests/classes/inner_classes_020.phpt new file mode 100644 index 0000000000000..a5366f5b4a3c5 --- /dev/null +++ b/tests/classes/inner_classes_020.phpt @@ -0,0 +1,23 @@ +--TEST-- +property types +--FILE-- +Inner $inner; + private class Inner {} + public function test(): void { + $this->inner = new self:>Inner(); + } +} + +$outer = new Outer(); +$outer->test(); +var_dump($outer->inner); +?> +--EXPECTF-- +Fatal error: Uncaught TypeError: Method test is public but returns a private class: Outer:>Inner in %s:%d +Stack trace: +#0 %s(%d): Outer::test() +#1 {main} + thrown in %s on line %d diff --git a/tests/classes/inner_classes_021.phpt b/tests/classes/inner_classes_021.phpt new file mode 100644 index 0000000000000..7def572cff602 --- /dev/null +++ b/tests/classes/inner_classes_021.phpt @@ -0,0 +1 @@ +--TEST-- From 269a4032472ae47295da2976653ee0545715a834 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Thu, 13 Mar 2025 17:53:26 +0100 Subject: [PATCH 18/65] move tests --- .../access_modifiers_001.phpt} | 0 .../access_modifiers_002.phpt} | 0 .../access_modifiers_003.phpt} | 0 .../access_modifiers_004.phpt} | 0 .../access_modifiers_005.phpt} | 0 .../access_modifiers_006.phpt} | 0 .../inner_classes/access_modifiers_007.phpt | 18 ++++++++++++++++ .../autoload_001.phpt} | 0 .../autoload_002.phpt} | 0 tests/classes/inner_classes/inheritance.phpt | 14 +++++++++++++ .../{ => inner_classes}/inner_classes.inc | 0 .../properties_001.phpt} | 0 .../reflection_001.phpt} | 0 .../return_types_001.phpt} | 0 .../return_types_002.phpt} | 0 .../return_types_003.phpt} | 0 .../return_types_004.phpt} | 0 .../return_types_005.phpt} | 0 .../inner_classes/return_types_006.phpt | 21 +++++++++++++++++++ .../simple_declaration_001.phpt} | 0 .../simple_declaration_002.phpt} | 0 .../simple_declaration_003.phpt} | 0 .../simple_declaration_004.phpt} | 0 .../static_variables.phpt} | 0 tests/classes/inner_classes_021.phpt | 1 - 25 files changed, 53 insertions(+), 1 deletion(-) rename tests/classes/{inner_classes_001.phpt => inner_classes/access_modifiers_001.phpt} (100%) rename tests/classes/{inner_classes_002.phpt => inner_classes/access_modifiers_002.phpt} (100%) rename tests/classes/{inner_classes_003.phpt => inner_classes/access_modifiers_003.phpt} (100%) rename tests/classes/{inner_classes_004.phpt => inner_classes/access_modifiers_004.phpt} (100%) rename tests/classes/{inner_classes_005.phpt => inner_classes/access_modifiers_005.phpt} (100%) rename tests/classes/{inner_classes_006.phpt => inner_classes/access_modifiers_006.phpt} (100%) create mode 100644 tests/classes/inner_classes/access_modifiers_007.phpt rename tests/classes/{inner_classes_018.phpt => inner_classes/autoload_001.phpt} (100%) rename tests/classes/{inner_classes_019.phpt => inner_classes/autoload_002.phpt} (100%) create mode 100644 tests/classes/inner_classes/inheritance.phpt rename tests/classes/{ => inner_classes}/inner_classes.inc (100%) rename tests/classes/{inner_classes_020.phpt => inner_classes/properties_001.phpt} (100%) rename tests/classes/{inner_classes_013.phpt => inner_classes/reflection_001.phpt} (100%) rename tests/classes/{inner_classes_010.phpt => inner_classes/return_types_001.phpt} (100%) rename tests/classes/{inner_classes_014.phpt => inner_classes/return_types_002.phpt} (100%) rename tests/classes/{inner_classes_015.phpt => inner_classes/return_types_003.phpt} (100%) rename tests/classes/{inner_classes_016.phpt => inner_classes/return_types_004.phpt} (100%) rename tests/classes/{inner_classes_017.phpt => inner_classes/return_types_005.phpt} (100%) create mode 100644 tests/classes/inner_classes/return_types_006.phpt rename tests/classes/{inner_classes_007.phpt => inner_classes/simple_declaration_001.phpt} (100%) rename tests/classes/{inner_classes_008.phpt => inner_classes/simple_declaration_002.phpt} (100%) rename tests/classes/{inner_classes_009.phpt => inner_classes/simple_declaration_003.phpt} (100%) rename tests/classes/{inner_classes_012.phpt => inner_classes/simple_declaration_004.phpt} (100%) rename tests/classes/{inner_classes_011.phpt => inner_classes/static_variables.phpt} (100%) delete mode 100644 tests/classes/inner_classes_021.phpt diff --git a/tests/classes/inner_classes_001.phpt b/tests/classes/inner_classes/access_modifiers_001.phpt similarity index 100% rename from tests/classes/inner_classes_001.phpt rename to tests/classes/inner_classes/access_modifiers_001.phpt diff --git a/tests/classes/inner_classes_002.phpt b/tests/classes/inner_classes/access_modifiers_002.phpt similarity index 100% rename from tests/classes/inner_classes_002.phpt rename to tests/classes/inner_classes/access_modifiers_002.phpt diff --git a/tests/classes/inner_classes_003.phpt b/tests/classes/inner_classes/access_modifiers_003.phpt similarity index 100% rename from tests/classes/inner_classes_003.phpt rename to tests/classes/inner_classes/access_modifiers_003.phpt diff --git a/tests/classes/inner_classes_004.phpt b/tests/classes/inner_classes/access_modifiers_004.phpt similarity index 100% rename from tests/classes/inner_classes_004.phpt rename to tests/classes/inner_classes/access_modifiers_004.phpt diff --git a/tests/classes/inner_classes_005.phpt b/tests/classes/inner_classes/access_modifiers_005.phpt similarity index 100% rename from tests/classes/inner_classes_005.phpt rename to tests/classes/inner_classes/access_modifiers_005.phpt diff --git a/tests/classes/inner_classes_006.phpt b/tests/classes/inner_classes/access_modifiers_006.phpt similarity index 100% rename from tests/classes/inner_classes_006.phpt rename to tests/classes/inner_classes/access_modifiers_006.phpt diff --git a/tests/classes/inner_classes/access_modifiers_007.phpt b/tests/classes/inner_classes/access_modifiers_007.phpt new file mode 100644 index 0000000000000..56da36c49c387 --- /dev/null +++ b/tests/classes/inner_classes/access_modifiers_007.phpt @@ -0,0 +1,18 @@ +--TEST-- +abstract inner classes +--FILE-- +Inner{}; + +var_dump($extended); +$reflection = new ReflectionClass('Outer:>Inner'); +var_dump($reflection->isAbstract()); +new Outer:>Inner(); +?> +--EXPECTF-- +last one fails diff --git a/tests/classes/inner_classes_018.phpt b/tests/classes/inner_classes/autoload_001.phpt similarity index 100% rename from tests/classes/inner_classes_018.phpt rename to tests/classes/inner_classes/autoload_001.phpt diff --git a/tests/classes/inner_classes_019.phpt b/tests/classes/inner_classes/autoload_002.phpt similarity index 100% rename from tests/classes/inner_classes_019.phpt rename to tests/classes/inner_classes/autoload_002.phpt diff --git a/tests/classes/inner_classes/inheritance.phpt b/tests/classes/inner_classes/inheritance.phpt new file mode 100644 index 0000000000000..c84be9d6978e1 --- /dev/null +++ b/tests/classes/inner_classes/inheritance.phpt @@ -0,0 +1,14 @@ +--TEST-- +inheritance +--FILE-- +Middle + class Inner2 extends Outer:>Middle {} // extends Outer + } +} +?> +--EXPECT-- diff --git a/tests/classes/inner_classes.inc b/tests/classes/inner_classes/inner_classes.inc similarity index 100% rename from tests/classes/inner_classes.inc rename to tests/classes/inner_classes/inner_classes.inc diff --git a/tests/classes/inner_classes_020.phpt b/tests/classes/inner_classes/properties_001.phpt similarity index 100% rename from tests/classes/inner_classes_020.phpt rename to tests/classes/inner_classes/properties_001.phpt diff --git a/tests/classes/inner_classes_013.phpt b/tests/classes/inner_classes/reflection_001.phpt similarity index 100% rename from tests/classes/inner_classes_013.phpt rename to tests/classes/inner_classes/reflection_001.phpt diff --git a/tests/classes/inner_classes_010.phpt b/tests/classes/inner_classes/return_types_001.phpt similarity index 100% rename from tests/classes/inner_classes_010.phpt rename to tests/classes/inner_classes/return_types_001.phpt diff --git a/tests/classes/inner_classes_014.phpt b/tests/classes/inner_classes/return_types_002.phpt similarity index 100% rename from tests/classes/inner_classes_014.phpt rename to tests/classes/inner_classes/return_types_002.phpt diff --git a/tests/classes/inner_classes_015.phpt b/tests/classes/inner_classes/return_types_003.phpt similarity index 100% rename from tests/classes/inner_classes_015.phpt rename to tests/classes/inner_classes/return_types_003.phpt diff --git a/tests/classes/inner_classes_016.phpt b/tests/classes/inner_classes/return_types_004.phpt similarity index 100% rename from tests/classes/inner_classes_016.phpt rename to tests/classes/inner_classes/return_types_004.phpt diff --git a/tests/classes/inner_classes_017.phpt b/tests/classes/inner_classes/return_types_005.phpt similarity index 100% rename from tests/classes/inner_classes_017.phpt rename to tests/classes/inner_classes/return_types_005.phpt diff --git a/tests/classes/inner_classes/return_types_006.phpt b/tests/classes/inner_classes/return_types_006.phpt new file mode 100644 index 0000000000000..1f99b50e165dd --- /dev/null +++ b/tests/classes/inner_classes/return_types_006.phpt @@ -0,0 +1,21 @@ +--TEST-- +returning private inner from inner method +--FILE-- +PrivateInner(); + } + } + + public function test() { return new self:>PrivateInner()->test(); } +} + +$foo = new Outer()->test(); +var_dump($foo); +?> +--EXPECT-- +object(Outer:>PrivateInner)#3 (0) { +} diff --git a/tests/classes/inner_classes_007.phpt b/tests/classes/inner_classes/simple_declaration_001.phpt similarity index 100% rename from tests/classes/inner_classes_007.phpt rename to tests/classes/inner_classes/simple_declaration_001.phpt diff --git a/tests/classes/inner_classes_008.phpt b/tests/classes/inner_classes/simple_declaration_002.phpt similarity index 100% rename from tests/classes/inner_classes_008.phpt rename to tests/classes/inner_classes/simple_declaration_002.phpt diff --git a/tests/classes/inner_classes_009.phpt b/tests/classes/inner_classes/simple_declaration_003.phpt similarity index 100% rename from tests/classes/inner_classes_009.phpt rename to tests/classes/inner_classes/simple_declaration_003.phpt diff --git a/tests/classes/inner_classes_012.phpt b/tests/classes/inner_classes/simple_declaration_004.phpt similarity index 100% rename from tests/classes/inner_classes_012.phpt rename to tests/classes/inner_classes/simple_declaration_004.phpt diff --git a/tests/classes/inner_classes_011.phpt b/tests/classes/inner_classes/static_variables.phpt similarity index 100% rename from tests/classes/inner_classes_011.phpt rename to tests/classes/inner_classes/static_variables.phpt diff --git a/tests/classes/inner_classes_021.phpt b/tests/classes/inner_classes_021.phpt deleted file mode 100644 index 7def572cff602..0000000000000 --- a/tests/classes/inner_classes_021.phpt +++ /dev/null @@ -1 +0,0 @@ ---TEST-- From a624033b5a130096b824fd3143cb92b5aa20589e Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Thu, 13 Mar 2025 20:34:53 +0100 Subject: [PATCH 19/65] add more tests and fix access modifiers --- Zend/zend_compile.c | 17 ++++++++++---- Zend/zend_language_parser.y | 16 ++++++------- .../inner_classes/access_modifiers_007.phpt | 15 +++++++++--- tests/classes/inner_classes/inheritance.phpt | 6 ++--- .../inner_classes/return_types_006.phpt | 2 +- .../classes/inner_classes/visibility_001.phpt | 23 +++++++++++++++++++ 6 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 tests/classes/inner_classes/visibility_001.phpt diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 59eae8fb17dc0..db1fbdd8e0d9f 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -893,12 +893,12 @@ uint32_t zend_modifier_token_to_flag(zend_modifier_target target, uint32_t token } break; case T_READONLY: - if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) { + if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP || target == ZEND_MODIFIER_TARGET_INNER_CLASS) { return ZEND_ACC_READONLY; } break; case T_ABSTRACT: - if (target == ZEND_MODIFIER_TARGET_METHOD || target == ZEND_MODIFIER_TARGET_PROPERTY) { + if (target == ZEND_MODIFIER_TARGET_METHOD || target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_INNER_CLASS) { return ZEND_ACC_ABSTRACT; } break; @@ -906,6 +906,7 @@ uint32_t zend_modifier_token_to_flag(zend_modifier_target target, uint32_t token if (target == ZEND_MODIFIER_TARGET_METHOD || target == ZEND_MODIFIER_TARGET_CONSTANT || target == ZEND_MODIFIER_TARGET_PROPERTY + || target == ZEND_MODIFIER_TARGET_INNER_CLASS || target == ZEND_MODIFIER_TARGET_PROPERTY_HOOK) { return ZEND_ACC_FINAL; } @@ -9195,13 +9196,21 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) // - final // - readonly // - abstract - ce->ce_flags |= decl->attr & (ZEND_ACC_FINAL|ZEND_ACC_READONLY|ZEND_ACC_ABSTRACT); + decl->flags |= decl->attr & ZEND_ACC_FINAL; + if (decl->attr & ZEND_ACC_ABSTRACT) { + decl->flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; + } + if (decl->attr & ZEND_ACC_READONLY) { + decl->flags |= ZEND_ACC_READONLY_CLASS & ZEND_ACC_NO_DYNAMIC_PROPERTIES; + } - // configure the const stand-ins for a nested class. This should only include: + // configure for a nested class. This should only include: // - public // - private // - protected int propFlags = decl->attr & (ZEND_ACC_PUBLIC|ZEND_ACC_PROTECTED|ZEND_ACC_PRIVATE); + // remove the flags from attrs + decl->attr &= ~(ZEND_ACC_PUBLIC|ZEND_ACC_PROTECTED|ZEND_ACC_PRIVATE|ZEND_ACC_FINAL|ZEND_ACC_ABSTRACT|ZEND_ACC_READONLY); // if a class is private or protected, we need to require the correct scope ce->required_scope = propFlags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED) ? CG(active_class_entry) : NULL; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 02f1263e844a0..68f4752774fa1 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -629,6 +629,14 @@ class_modifier: | T_READONLY { $$ = ZEND_ACC_READONLY_CLASS|ZEND_ACC_NO_DYNAMIC_PROPERTIES; } ; +inner_class_modifiers: + non_empty_member_modifiers + { $$ = zend_modifier_list_to_flags(ZEND_MODIFIER_TARGET_INNER_CLASS, $1); + if (!$$) { YYERROR; } } + | %empty + { $$ = ZEND_ACC_PUBLIC; } +; + trait_declaration_statement: T_TRAIT { $$ = CG(zend_lineno); } T_STRING backup_doc_comment '{' class_statement_list '}' @@ -956,14 +964,6 @@ inner_class_statement: { $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, $3, $6, zend_ast_get_str($2), $4, $5, $8, NULL, NULL); } ; -inner_class_modifiers: - non_empty_member_modifiers - { $$ = zend_modifier_list_to_flags(ZEND_MODIFIER_TARGET_INNER_CLASS, $1); - if (!$$) { YYERROR; } } - | %empty - { $$ = ZEND_ACC_PUBLIC; } -; - attributed_class_statement: property_modifiers optional_type_without_static property_list ';' { $$ = zend_ast_create(ZEND_AST_PROP_GROUP, $2, $3, NULL); diff --git a/tests/classes/inner_classes/access_modifiers_007.phpt b/tests/classes/inner_classes/access_modifiers_007.phpt index 56da36c49c387..d1177412939f1 100644 --- a/tests/classes/inner_classes/access_modifiers_007.phpt +++ b/tests/classes/inner_classes/access_modifiers_007.phpt @@ -4,10 +4,12 @@ abstract inner classes Inner{}; +class Extended extends Outer:>Inner {} + +$extended = new Extended(); var_dump($extended); $reflection = new ReflectionClass('Outer:>Inner'); @@ -15,4 +17,11 @@ var_dump($reflection->isAbstract()); new Outer:>Inner(); ?> --EXPECTF-- -last one fails +object(Extended)#1 (0) { +} +bool(true) + +Fatal error: Uncaught Error: Cannot instantiate abstract class Outer:>Inner in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/tests/classes/inner_classes/inheritance.phpt b/tests/classes/inner_classes/inheritance.phpt index c84be9d6978e1..4addb7b02f61d 100644 --- a/tests/classes/inner_classes/inheritance.phpt +++ b/tests/classes/inner_classes/inheritance.phpt @@ -5,9 +5,9 @@ inheritance class Outer { abstract class Other {} - class Middle extends Other { - class Inner1 {} // extends Outer:>Middle - class Inner2 extends Outer:>Middle {} // extends Outer + class Middle extends Outer:>Other { + class Inner1 extends Outer:>Other {} + class Inner2 extends Outer:>Middle {} } } ?> diff --git a/tests/classes/inner_classes/return_types_006.phpt b/tests/classes/inner_classes/return_types_006.phpt index 1f99b50e165dd..cff19b727ad54 100644 --- a/tests/classes/inner_classes/return_types_006.phpt +++ b/tests/classes/inner_classes/return_types_006.phpt @@ -10,7 +10,7 @@ class Outer { } } - public function test() { return new self:>PrivateInner()->test(); } + public function test(): mixed { return new self:>PrivateInner()->test(); } } $foo = new Outer()->test(); diff --git a/tests/classes/inner_classes/visibility_001.phpt b/tests/classes/inner_classes/visibility_001.phpt new file mode 100644 index 0000000000000..6c880452326ef --- /dev/null +++ b/tests/classes/inner_classes/visibility_001.phpt @@ -0,0 +1,23 @@ +--TEST-- +outer class visibility +--FILE-- +Inner $inner) {} + + public function reset(): void { + $prev = $this->inner; + $this->inner = new Outer:>Inner(); + var_dump($prev === $this->inner); + } + } + public static function test(): void { + new self:>Other(new Outer:>Inner()); + } +} +Outer::test(); +?> +--EXPECT-- From e8d757067d2d11b86816d26631de2f70a4541e22 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Thu, 13 Mar 2025 21:22:46 +0100 Subject: [PATCH 20/65] add support for lexical scope --- Zend/zend.h | 1 + Zend/zend_compile.c | 1 + 2 files changed, 2 insertions(+) diff --git a/Zend/zend.h b/Zend/zend.h index 81ced0cf41a1d..912008d43d997 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -165,6 +165,7 @@ struct _zend_class_entry { HashTable constants_table; zend_class_entry *required_scope; + zend_class_entry *lexical_scope; char required_scope_absolute; ZEND_MAP_PTR_DEF(zend_class_mutable_data*, mutable_data); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index db1fbdd8e0d9f..6f284b1ee53e9 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -9215,6 +9215,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) // if a class is private or protected, we need to require the correct scope ce->required_scope = propFlags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED) ? CG(active_class_entry) : NULL; ce->required_scope_absolute = propFlags & ZEND_ACC_PRIVATE ? true : false; + ce->lexical_scope = CG(active_class_entry); // ensure the class is treated as a top-level class and not an anon class toplevel = true; From 2e1d287c742bfc661d1b03c02c4ea837e04f884b Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 09:02:42 +0100 Subject: [PATCH 21/65] handle type visibility --- Zend/zend_execute.c | 45 +++++++++++++++++++ Zend/zend_object_handlers.c | 4 ++ Zend/zend_vm_def.h | 22 ++++++--- .../classes/inner_classes/properties_001.phpt | 23 ---------- .../classes/inner_classes/visibility_001.phpt | 28 ++++++------ .../classes/inner_classes/visibility_002.phpt | 30 +++++++++++++ .../classes/inner_classes/visibility_003.phpt | 30 +++++++++++++ .../classes/inner_classes/visibility_004.phpt | 25 +++++++++++ 8 files changed, 165 insertions(+), 42 deletions(-) delete mode 100644 tests/classes/inner_classes/properties_001.phpt create mode 100644 tests/classes/inner_classes/visibility_002.phpt create mode 100644 tests/classes/inner_classes/visibility_003.phpt create mode 100644 tests/classes/inner_classes/visibility_004.phpt diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index efa759f334ef8..3a983e7086885 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1045,12 +1045,57 @@ static zend_always_inline bool i_zend_check_property_type(const zend_property_in return zend_verify_scalar_type_hint(type_mask, property, strict, 0); } +static zend_always_inline bool zend_check_class_visibility(const zend_class_entry *ce, const zend_property_info *info, uint32_t current_visibility) { + // a public class is always visible + if (!ce->required_scope) { + return 1; + } + + // a protected class is visible if it is a subclass of the lexical scope and the current visibility is protected or private + if (!ce->required_scope_absolute) { + if (current_visibility & ZEND_ACC_PUBLIC) { + zend_type_error("Cannot assign private %s to higher visibile property %s::%s", + ZSTR_VAL(ce->name), + ZSTR_VAL(info->ce->name), + zend_get_unmangled_property_name(info->name)); + return 0; + } + + return 0; + } + + // a private class is visible if it is the same class as the lexical scope and the current visibility is private + if (ce->required_scope_absolute && current_visibility & ZEND_ACC_PRIVATE) { + return 1; + } + + zend_type_error("Cannot assign private %s to higher visibile property %s::%s", + ZSTR_VAL(ce->name), + ZSTR_VAL(info->ce->name), + zend_get_unmangled_property_name(info->name)); + + return 0; +} + static zend_always_inline bool i_zend_verify_property_type(const zend_property_info *info, zval *property, bool strict) { + if(Z_TYPE_P(property) == IS_OBJECT && !zend_check_class_visibility(Z_OBJCE_P(property), info, info->flags)) { + zend_verify_property_type_error(info, property); + return 0; + } + if (i_zend_check_property_type(info, property, strict)) { return 1; } + // todo: + // 1: add a flag to the type so we can tell the type is an inner class + // 2: use said flag to flag the property info + // 3: same with parameters/args too + // 4: create a simple function to take a visibility flag and ce, it should return SUCCESS if the ce can be used + // 5: if we have an inner class in a prop/arg, we validate it can be returned (do not autoload) by looping over types + // that are inner classes and looking up the ce. If it is not autoloaded, then it is not going to match the type anyway. + zend_verify_property_type_error(info, property); return 0; } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index f2c2886eeb2be..9956c3f70e320 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -401,6 +401,10 @@ static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *c if (property_info->ce != ce) { goto dynamic; } else { + if (scope && scope->lexical_scope && scope->lexical_scope == ce) { + // Allow access to private properties from within the same outer class + goto found; + } wrong: /* Information was available, but we were denied access. Error out. */ if (!silent) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 2d13f49a70cb1..e45f799c5b043 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1869,12 +1869,22 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S } if (inner_ce->required_scope) { - if (inner_ce->required_scope_absolute && inner_ce->required_scope != scope) { - zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); - } else if (scope == NULL || !instanceof_function(scope, inner_ce->required_scope)) { - zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); + if (inner_ce->required_scope_absolute) { + // for private classes, we check if the scope we are currently in has access + if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) { + // we are in the correct scope + } else { + zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } + } else { + // for protected classes, we check if the scope is an instance of the required scope + if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) { + // we are in the correct scope + } else { + zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } } } diff --git a/tests/classes/inner_classes/properties_001.phpt b/tests/classes/inner_classes/properties_001.phpt deleted file mode 100644 index a5366f5b4a3c5..0000000000000 --- a/tests/classes/inner_classes/properties_001.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -property types ---FILE-- -Inner $inner; - private class Inner {} - public function test(): void { - $this->inner = new self:>Inner(); - } -} - -$outer = new Outer(); -$outer->test(); -var_dump($outer->inner); -?> ---EXPECTF-- -Fatal error: Uncaught TypeError: Method test is public but returns a private class: Outer:>Inner in %s:%d -Stack trace: -#0 %s(%d): Outer::test() -#1 {main} - thrown in %s on line %d diff --git a/tests/classes/inner_classes/visibility_001.phpt b/tests/classes/inner_classes/visibility_001.phpt index 6c880452326ef..0473686689403 100644 --- a/tests/classes/inner_classes/visibility_001.phpt +++ b/tests/classes/inner_classes/visibility_001.phpt @@ -4,20 +4,22 @@ outer class visibility Inner $inner) {} + private class Inner {} + public Outer:>Inner $illegal; - public function reset(): void { - $prev = $this->inner; - $this->inner = new Outer:>Inner(); - var_dump($prev === $this->inner); + public function test(): void { + $this->illegal = new Outer:>Inner(); } - } - public static function test(): void { - new self:>Other(new Outer:>Inner()); - } } -Outer::test(); + +$x = new Outer(); +$x->test(); + +var_dump($x); ?> ---EXPECT-- +--EXPECTF-- +Fatal error: Uncaught TypeError: Cannot assign private Outer:>Inner to higher visibile property Outer::illegal in %s:%d +Stack trace: +#0 %s(%d): Outer->test() +#1 {main} + thrown in %s on line %d diff --git a/tests/classes/inner_classes/visibility_002.phpt b/tests/classes/inner_classes/visibility_002.phpt new file mode 100644 index 0000000000000..8e99b87d15a15 --- /dev/null +++ b/tests/classes/inner_classes/visibility_002.phpt @@ -0,0 +1,30 @@ +--TEST-- +accessing outer class private vars +--FILE-- +illegal = $this; + } + } + private Outer:>Inner $illegal; + + public function test(): void { + new Outer:>Inner()->test($this); + } +} + +$x = new Outer(); +$x->test(); + +var_dump($x); + +?> +--EXPECT-- +object(Outer)#1 (1) { + ["illegal":"Outer":private]=> + object(Outer:>Inner)#2 (0) { + } +} diff --git a/tests/classes/inner_classes/visibility_003.phpt b/tests/classes/inner_classes/visibility_003.phpt new file mode 100644 index 0000000000000..66f42b2707838 --- /dev/null +++ b/tests/classes/inner_classes/visibility_003.phpt @@ -0,0 +1,30 @@ +--TEST-- +accessing outer protected vars +--FILE-- +illegal = $this; + } + } + private Outer:>Inner $illegal; + + public function test(): void { + new Outer:>Inner()->test($this); + } +} + +$x = new Outer(); +$x->test(); + +var_dump($x); + +?> +--EXPECT-- +object(Outer)#1 (1) { + ["illegal":"Outer":private]=> + object(Outer:>Inner)#2 (0) { + } +} diff --git a/tests/classes/inner_classes/visibility_004.phpt b/tests/classes/inner_classes/visibility_004.phpt new file mode 100644 index 0000000000000..3115858fee756 --- /dev/null +++ b/tests/classes/inner_classes/visibility_004.phpt @@ -0,0 +1,25 @@ +--TEST-- +outer class visibility +--FILE-- +Inner $illegal; + + public function test(): void { + $this->illegal = new Outer:>Inner(); + } +} + +$x = new Outer(); +$x->test(); + +var_dump($x); +?> +--EXPECTF-- +Fatal error: Uncaught TypeError: Cannot assign private Outer:>Inner to higher visibile property Outer::illegal in %s:%d +Stack trace: +#0 %s(%d): Outer->test() +#1 {main} + thrown in %s on line %d From d33cd2f07d13cb848553a1373a6423a40a04bd9b Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 09:46:20 +0100 Subject: [PATCH 22/65] fix opcache --- Zend/zend_compile.c | 5 +- Zend/zend_execute.c | 10 +--- Zend/zend_vm_execute.h | 114 +++++++++++++++++++++++++++++++------ ext/opcache/zend_persist.c | 9 +++ 4 files changed, 108 insertions(+), 30 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 6f284b1ee53e9..a72d5dd8c144d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2943,9 +2943,7 @@ static void zend_compile_inner_class_ref(znode *result, zend_ast *ast, uint32_t zend_compile_expr(&inner_node, inner_class); } - zend_op *opline = zend_emit_op(result, ZEND_FETCH_INNER_CLASS, &outer_node, &inner_node); - // ensure we allocate two slots to prevent an issue with static method access - opline->extended_value = zend_alloc_cache_slots(2); + zend_emit_op(result, ZEND_FETCH_INNER_CLASS, &outer_node, &inner_node); } /* }}} */ @@ -9222,6 +9220,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) } else { name = zend_prefix_with_ns(unqualified_name); ce->required_scope = NULL; + ce->lexical_scope = NULL; } name = zend_new_interned_string(name); lcname = zend_string_tolower(name); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 3a983e7086885..aba772bb9d13c 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1061,7 +1061,7 @@ static zend_always_inline bool zend_check_class_visibility(const zend_class_entr return 0; } - return 0; + return 1; } // a private class is visible if it is the same class as the lexical scope and the current visibility is private @@ -1088,14 +1088,6 @@ static zend_always_inline bool i_zend_verify_property_type(const zend_property_i return 1; } - // todo: - // 1: add a flag to the type so we can tell the type is an inner class - // 2: use said flag to flag the property info - // 3: same with parameters/args too - // 4: create a simple function to take a visibility flag and ce, it should return SUCCESS if the ce can be used - // 5: if we have an inner class in a prop/arg, we validate it can be returned (do not autoload) by looping over types - // that are inner classes and looking up the ce. If it is not autoloaded, then it is not going to match the type anyway. - zend_verify_property_type_error(info, property); return 0; } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index cde630e1ab345..eab173b2a7ffc 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6682,12 +6682,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C } if (inner_ce->required_scope) { - if (inner_ce->required_scope_absolute && inner_ce->required_scope != scope) { - zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); - } else if (scope == NULL || !instanceof_function(scope, inner_ce->required_scope)) { - zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); + if (inner_ce->required_scope_absolute) { + // for private classes, we check if the scope we are currently in has access + if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) { + // we are in the correct scope + } else { + zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } + } else { + // for protected classes, we check if the scope is an instance of the required scope + if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) { + // we are in the correct scope + } else { + zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } } } @@ -7402,6 +7412,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C IS_CONST == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ + } else if (IS_CONST != IS_CONST && + IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { @@ -9972,6 +9986,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C (IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ + } else if (IS_CONST != IS_CONST && + (IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -10726,6 +10744,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C IS_UNUSED == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ + } else if (IS_CONST != IS_CONST && + IS_UNUSED == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { function_name = NULL; if (IS_UNUSED != IS_CONST) { @@ -12474,6 +12496,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C IS_CV == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ + } else if (IS_CONST != IS_CONST && + IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { function_name = EX_VAR(opline->op2.var); if (IS_CV != IS_CONST) { @@ -16289,12 +16315,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ } if (inner_ce->required_scope) { - if (inner_ce->required_scope_absolute && inner_ce->required_scope != scope) { - zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); - } else if (scope == NULL || !instanceof_function(scope, inner_ce->required_scope)) { - zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); + if (inner_ce->required_scope_absolute) { + // for private classes, we check if the scope we are currently in has access + if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) { + // we are in the correct scope + } else { + zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } + } else { + // for protected classes, we check if the scope is an instance of the required scope + if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) { + // we are in the correct scope + } else { + zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } } } @@ -25612,6 +25648,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V IS_CONST == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ + } else if (IS_VAR != IS_CONST && + IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { @@ -28541,6 +28581,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V (IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ + } else if (IS_VAR != IS_CONST && + (IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -30047,6 +30091,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V IS_UNUSED == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ + } else if (IS_VAR != IS_CONST && + IS_UNUSED == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { function_name = NULL; if (IS_UNUSED != IS_CONST) { @@ -33000,6 +33048,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V IS_CV == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ + } else if (IS_VAR != IS_CONST && + IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { function_name = EX_VAR(opline->op2.var); if (IS_CV != IS_CONST) { @@ -34014,12 +34066,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_ } if (inner_ce->required_scope) { - if (inner_ce->required_scope_absolute && inner_ce->required_scope != scope) { - zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); - } else if (scope == NULL || !instanceof_function(scope, inner_ce->required_scope)) { - zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); + if (inner_ce->required_scope_absolute) { + // for private classes, we check if the scope we are currently in has access + if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) { + // we are in the correct scope + } else { + zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } + } else { + // for protected classes, we check if the scope is an instance of the required scope + if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) { + // we are in the correct scope + } else { + zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); + HANDLE_EXCEPTION(); + } } } @@ -35355,6 +35417,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U IS_CONST == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ + } else if (IS_UNUSED != IS_CONST && + IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { @@ -37520,6 +37586,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U (IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ + } else if (IS_UNUSED != IS_CONST && + (IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -37927,6 +37997,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U IS_UNUSED == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ + } else if (IS_UNUSED != IS_CONST && + IS_UNUSED == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { function_name = NULL; if (IS_UNUSED != IS_CONST) { @@ -40175,6 +40249,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U IS_CV == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ + } else if (IS_UNUSED != IS_CONST && + IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { function_name = EX_VAR(opline->op2.var); if (IS_CV != IS_CONST) { diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index fa82f997ee3a5..771101462b510 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -1131,6 +1131,15 @@ void zend_update_required_scope(zend_class_entry *ce) ce->required_scope = r; } } + + if (ce->lexical_scope) { + zend_class_entry *lexical_scope = ce->lexical_scope; + + zend_class_entry *l = zend_shared_alloc_get_xlat_entry(lexical_scope); + if (l) { + ce->lexical_scope = l; + } + } } void zend_update_parent_ce(zend_class_entry *ce) From a7364af1e58977ca6840e75aca7c1508acf073bd Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 09:49:03 +0100 Subject: [PATCH 23/65] fix test --- Zend/zend_execute.c | 2 +- tests/classes/inner_classes/visibility_004.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index aba772bb9d13c..d734b590bc3f7 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1054,7 +1054,7 @@ static zend_always_inline bool zend_check_class_visibility(const zend_class_entr // a protected class is visible if it is a subclass of the lexical scope and the current visibility is protected or private if (!ce->required_scope_absolute) { if (current_visibility & ZEND_ACC_PUBLIC) { - zend_type_error("Cannot assign private %s to higher visibile property %s::%s", + zend_type_error("Cannot assign protected %s to higher visibile property %s::%s", ZSTR_VAL(ce->name), ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); diff --git a/tests/classes/inner_classes/visibility_004.phpt b/tests/classes/inner_classes/visibility_004.phpt index 3115858fee756..38390f65c830e 100644 --- a/tests/classes/inner_classes/visibility_004.phpt +++ b/tests/classes/inner_classes/visibility_004.phpt @@ -18,7 +18,7 @@ $x->test(); var_dump($x); ?> --EXPECTF-- -Fatal error: Uncaught TypeError: Cannot assign private Outer:>Inner to higher visibile property Outer::illegal in %s:%d +Fatal error: Uncaught TypeError: Cannot assign protected Outer:>Inner to higher visibile property Outer::illegal in %s:%d Stack trace: #0 %s(%d): Outer->test() #1 {main} From 63a08821bb67d983e858d8c241679cdc11d67836 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 10:18:45 +0100 Subject: [PATCH 24/65] refine some error messages --- Zend/zend_vm_def.h | 14 ++--- Zend/zend_vm_execute.h | 54 +++++++++---------- tests/classes/inner_classes/autoload_002.phpt | 2 +- tests/classes/inner_classes/errors_001.phpt | 9 ++++ tests/classes/inner_classes/errors_002.phpt | 12 +++++ .../inner_classes/return_types_002.phpt | 2 +- .../inner_classes/return_types_003.phpt | 2 +- .../inner_classes/return_types_004.phpt | 2 +- .../inner_classes/return_types_005.phpt | 2 +- 9 files changed, 60 insertions(+), 39 deletions(-) create mode 100644 tests/classes/inner_classes/errors_001.phpt create mode 100644 tests/classes/inner_classes/errors_002.phpt diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index e45f799c5b043..abb80d07de3bb 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1812,7 +1812,7 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv)); if (!outer_ce) { - zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_P(outer_class_zv)); + zend_error(E_ERROR, "Outer class '%s' not found for inner class %s:>%s", Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); HANDLE_EXCEPTION(); } } else if (OP1_TYPE == IS_UNUSED) { @@ -1864,7 +1864,7 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S inner_ce = zend_lookup_class(full_class_name); if (!inner_ce) { - zend_error(E_ERROR, "Class '%s' not found", ZSTR_VAL(full_class_name)); + zend_error(E_ERROR, "Inner class '%s' not found in outer class %s", ZSTR_VAL(full_class_name), ZSTR_VAL(outer_ce->name)); HANDLE_EXCEPTION(); } @@ -1874,7 +1874,7 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) { // we are in the correct scope } else { - zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); + zend_error(E_ERROR, "Cannot access private inner class '%s'", ZSTR_VAL(full_class_name)); HANDLE_EXCEPTION(); } } else { @@ -1882,7 +1882,7 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) { // we are in the correct scope } else { - zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); + zend_error(E_ERROR, "Cannot access protected inner class '%s'", ZSTR_VAL(full_class_name)); HANDLE_EXCEPTION(); } } @@ -4529,15 +4529,15 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV if (Z_OBJCE_P(retval_ptr)->required_scope) { if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { - zend_type_error("Method %s is public but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Public method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } else { - zend_type_error("Method %s is public but returns a protected class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Public method %s cannot return protected class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } } else if (EX(func)->common.fn_flags & ZEND_ACC_PROTECTED) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute && Z_OBJCE_P(retval_ptr)->required_scope != EX(func)->common.scope) { - zend_type_error("Method %s is protected but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Protected method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index eab173b2a7ffc..2e6a66fd0730b 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6625,7 +6625,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv)); if (!outer_ce) { - zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_P(outer_class_zv)); + zend_error(E_ERROR, "Outer class '%s' not found for inner class %s:>%s", Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); HANDLE_EXCEPTION(); } } else if (IS_CONST == IS_UNUSED) { @@ -6677,7 +6677,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C inner_ce = zend_lookup_class(full_class_name); if (!inner_ce) { - zend_error(E_ERROR, "Class '%s' not found", ZSTR_VAL(full_class_name)); + zend_error(E_ERROR, "Inner class '%s' not found in outer class %s", ZSTR_VAL(full_class_name), ZSTR_VAL(outer_ce->name)); HANDLE_EXCEPTION(); } @@ -6687,7 +6687,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) { // we are in the correct scope } else { - zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); + zend_error(E_ERROR, "Cannot access private inner class '%s'", ZSTR_VAL(full_class_name)); HANDLE_EXCEPTION(); } } else { @@ -6695,7 +6695,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) { // we are in the correct scope } else { - zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); + zend_error(E_ERROR, "Cannot access protected inner class '%s'", ZSTR_VAL(full_class_name)); HANDLE_EXCEPTION(); } } @@ -10902,15 +10902,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP if (Z_OBJCE_P(retval_ptr)->required_scope) { if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { - zend_type_error("Method %s is public but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Public method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } else { - zend_type_error("Method %s is public but returns a protected class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Public method %s cannot return protected class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } } else if (EX(func)->common.fn_flags & ZEND_ACC_PROTECTED) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute && Z_OBJCE_P(retval_ptr)->required_scope != EX(func)->common.scope) { - zend_type_error("Method %s is protected but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Protected method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } } @@ -16258,7 +16258,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv)); if (!outer_ce) { - zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_P(outer_class_zv)); + zend_error(E_ERROR, "Outer class '%s' not found for inner class %s:>%s", Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); HANDLE_EXCEPTION(); } } else if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { @@ -16310,7 +16310,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ inner_ce = zend_lookup_class(full_class_name); if (!inner_ce) { - zend_error(E_ERROR, "Class '%s' not found", ZSTR_VAL(full_class_name)); + zend_error(E_ERROR, "Inner class '%s' not found in outer class %s", ZSTR_VAL(full_class_name), ZSTR_VAL(outer_ce->name)); HANDLE_EXCEPTION(); } @@ -16320,7 +16320,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) { // we are in the correct scope } else { - zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); + zend_error(E_ERROR, "Cannot access private inner class '%s'", ZSTR_VAL(full_class_name)); HANDLE_EXCEPTION(); } } else { @@ -16328,7 +16328,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) { // we are in the correct scope } else { - zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); + zend_error(E_ERROR, "Cannot access protected inner class '%s'", ZSTR_VAL(full_class_name)); HANDLE_EXCEPTION(); } } @@ -21755,15 +21755,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN if (Z_OBJCE_P(retval_ptr)->required_scope) { if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { - zend_type_error("Method %s is public but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Public method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } else { - zend_type_error("Method %s is public but returns a protected class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Public method %s cannot return protected class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } } else if (EX(func)->common.fn_flags & ZEND_ACC_PROTECTED) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute && Z_OBJCE_P(retval_ptr)->required_scope != EX(func)->common.scope) { - zend_type_error("Method %s is protected but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Protected method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } } @@ -30249,15 +30249,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN if (Z_OBJCE_P(retval_ptr)->required_scope) { if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { - zend_type_error("Method %s is public but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Public method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } else { - zend_type_error("Method %s is public but returns a protected class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Public method %s cannot return protected class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } } else if (EX(func)->common.fn_flags & ZEND_ACC_PROTECTED) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute && Z_OBJCE_P(retval_ptr)->required_scope != EX(func)->common.scope) { - zend_type_error("Method %s is protected but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Protected method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } } @@ -34009,7 +34009,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_ zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv)); if (!outer_ce) { - zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_P(outer_class_zv)); + zend_error(E_ERROR, "Outer class '%s' not found for inner class %s:>%s", Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); HANDLE_EXCEPTION(); } } else if (IS_UNUSED == IS_UNUSED) { @@ -34061,7 +34061,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_ inner_ce = zend_lookup_class(full_class_name); if (!inner_ce) { - zend_error(E_ERROR, "Class '%s' not found", ZSTR_VAL(full_class_name)); + zend_error(E_ERROR, "Inner class '%s' not found in outer class %s", ZSTR_VAL(full_class_name), ZSTR_VAL(outer_ce->name)); HANDLE_EXCEPTION(); } @@ -34071,7 +34071,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_ if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) { // we are in the correct scope } else { - zend_error(E_ERROR, "Class '%s' is private", ZSTR_VAL(full_class_name)); + zend_error(E_ERROR, "Cannot access private inner class '%s'", ZSTR_VAL(full_class_name)); HANDLE_EXCEPTION(); } } else { @@ -34079,7 +34079,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_ if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) { // we are in the correct scope } else { - zend_error(E_ERROR, "Class '%s' is protected", ZSTR_VAL(full_class_name)); + zend_error(E_ERROR, "Cannot access protected inner class '%s'", ZSTR_VAL(full_class_name)); HANDLE_EXCEPTION(); } } @@ -38155,15 +38155,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED if (Z_OBJCE_P(retval_ptr)->required_scope) { if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { - zend_type_error("Method %s is public but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Public method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } else { - zend_type_error("Method %s is public but returns a protected class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Public method %s cannot return protected class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } } else if (EX(func)->common.fn_flags & ZEND_ACC_PROTECTED) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute && Z_OBJCE_P(retval_ptr)->required_scope != EX(func)->common.scope) { - zend_type_error("Method %s is protected but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Protected method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } } @@ -50974,15 +50974,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU if (Z_OBJCE_P(retval_ptr)->required_scope) { if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { - zend_type_error("Method %s is public but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Public method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } else { - zend_type_error("Method %s is public but returns a protected class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Public method %s cannot return protected class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } } else if (EX(func)->common.fn_flags & ZEND_ACC_PROTECTED) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute && Z_OBJCE_P(retval_ptr)->required_scope != EX(func)->common.scope) { - zend_type_error("Method %s is protected but returns a private class: %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); + zend_type_error("Protected method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); HANDLE_EXCEPTION(); } } diff --git a/tests/classes/inner_classes/autoload_002.phpt b/tests/classes/inner_classes/autoload_002.phpt index 4259bc8553162..f2cbd1fc6cc74 100644 --- a/tests/classes/inner_classes/autoload_002.phpt +++ b/tests/classes/inner_classes/autoload_002.phpt @@ -13,4 +13,4 @@ var_dump($line); --EXPECTF-- autoload(inner_classes) -Fatal error: Class 'inner_classes:>Line' is private in %s on line %d +Fatal error: Cannot access private inner class 'inner_classes:>Line' in %s diff --git a/tests/classes/inner_classes/errors_001.phpt b/tests/classes/inner_classes/errors_001.phpt new file mode 100644 index 0000000000000..f4817e95351ce --- /dev/null +++ b/tests/classes/inner_classes/errors_001.phpt @@ -0,0 +1,9 @@ +--TEST-- +no outer class +--FILE-- +Inner(); +?> +--EXPECTF-- +Fatal error: Outer class 'Outer' not found for inner class Outer:>Inner in %s on line %d diff --git a/tests/classes/inner_classes/errors_002.phpt b/tests/classes/inner_classes/errors_002.phpt new file mode 100644 index 0000000000000..c9e1c08147675 --- /dev/null +++ b/tests/classes/inner_classes/errors_002.phpt @@ -0,0 +1,12 @@ +--TEST-- +inner class not found +--FILE-- +Inner(); +?> +--EXPECTF-- +Fatal error: Inner class 'Outer:>Inner' not found in outer class Outer in %s on line %d diff --git a/tests/classes/inner_classes/return_types_002.phpt b/tests/classes/inner_classes/return_types_002.phpt index 80aab3c3e68b2..b2929a6fdd148 100644 --- a/tests/classes/inner_classes/return_types_002.phpt +++ b/tests/classes/inner_classes/return_types_002.phpt @@ -29,4 +29,4 @@ var_dump($outer->getInner()); object(Outer:>Inner)#2 (0) { } -Fatal error: Class 'Outer:>Inner' is private in %s on line %d +Fatal error: Cannot access private inner class 'Outer:>Inner' in %s on line %d diff --git a/tests/classes/inner_classes/return_types_003.phpt b/tests/classes/inner_classes/return_types_003.phpt index e96529b108d0d..4326566956ca2 100644 --- a/tests/classes/inner_classes/return_types_003.phpt +++ b/tests/classes/inner_classes/return_types_003.phpt @@ -26,7 +26,7 @@ var_dump(new Outer:>Inner()); object(Outer:>Inner)#2 (0) { } -Fatal error: Uncaught TypeError: Method getInner is public but returns a protected class: Outer:>Inner in %s:%d +Fatal error: Uncaught TypeError: Public method getInner cannot return protected class Outer:>Inner in %s:%d Stack trace: #0 %s(%d): Foo->getInner() #1 {main} diff --git a/tests/classes/inner_classes/return_types_004.phpt b/tests/classes/inner_classes/return_types_004.phpt index efc50b6bca1d5..0fbeacd246297 100644 --- a/tests/classes/inner_classes/return_types_004.phpt +++ b/tests/classes/inner_classes/return_types_004.phpt @@ -19,7 +19,7 @@ var_dump($r); test($r); ?> --EXPECTF-- -Fatal error: Uncaught TypeError: Method getInner is public but returns a private class: Outer:>Inner in %s:%d +Fatal error: Uncaught TypeError: Public method getInner cannot return private class Outer:>Inner in %s:%d Stack trace: #0 %s(%d): Outer::getInner() #1 {main} diff --git a/tests/classes/inner_classes/return_types_005.phpt b/tests/classes/inner_classes/return_types_005.phpt index 4e804831479a3..5c2ed4ae7de86 100644 --- a/tests/classes/inner_classes/return_types_005.phpt +++ b/tests/classes/inner_classes/return_types_005.phpt @@ -19,7 +19,7 @@ var_dump($r); test($r); ?> --EXPECTF-- -Fatal error: Uncaught TypeError: Method getInner is public but returns a protected class: Outer:>Inner in %s:%d +Fatal error: Uncaught TypeError: Public method getInner cannot return protected class Outer:>Inner in %s:%d Stack trace: #0 %s(%d): Outer::getInner() #1 {main} From aafbda44479f49d9451ac20dfb090aac649a81f4 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 10:47:12 +0100 Subject: [PATCH 25/65] add type check to return type --- Zend/zend_vm_def.h | 2 +- Zend/zend_vm_execute.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index abb80d07de3bb..1754c5b75bb41 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4526,7 +4526,7 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV SAVE_OPLINE(); - if (Z_OBJCE_P(retval_ptr)->required_scope) { + if (Z_TYPE_P(retval_ptr) == IS_OBJECT && Z_OBJCE_P(retval_ptr)->required_scope) { if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { zend_type_error("Public method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2e6a66fd0730b..5f25118af52d4 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -10899,7 +10899,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP SAVE_OPLINE(); - if (Z_OBJCE_P(retval_ptr)->required_scope) { + if (Z_TYPE_P(retval_ptr) == IS_OBJECT && Z_OBJCE_P(retval_ptr)->required_scope) { if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { zend_type_error("Public method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); @@ -21752,7 +21752,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN SAVE_OPLINE(); - if (Z_OBJCE_P(retval_ptr)->required_scope) { + if (Z_TYPE_P(retval_ptr) == IS_OBJECT && Z_OBJCE_P(retval_ptr)->required_scope) { if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { zend_type_error("Public method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); @@ -30246,7 +30246,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN SAVE_OPLINE(); - if (Z_OBJCE_P(retval_ptr)->required_scope) { + if (Z_TYPE_P(retval_ptr) == IS_OBJECT && Z_OBJCE_P(retval_ptr)->required_scope) { if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { zend_type_error("Public method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); @@ -38152,7 +38152,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED SAVE_OPLINE(); - if (Z_OBJCE_P(retval_ptr)->required_scope) { + if (Z_TYPE_P(retval_ptr) == IS_OBJECT && Z_OBJCE_P(retval_ptr)->required_scope) { if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { zend_type_error("Public method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); @@ -50971,7 +50971,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU SAVE_OPLINE(); - if (Z_OBJCE_P(retval_ptr)->required_scope) { + if (Z_TYPE_P(retval_ptr) == IS_OBJECT && Z_OBJCE_P(retval_ptr)->required_scope) { if (EX(func)->common.fn_flags & ZEND_ACC_PUBLIC) { if (Z_OBJCE_P(retval_ptr)->required_scope_absolute) { zend_type_error("Public method %s cannot return private class %s", ZSTR_VAL(EX(func)->common.function_name), ZSTR_VAL(Z_OBJCE_P(retval_ptr)->name)); From 0966e30b51579747ba3f68cd0228fa31a4708ca5 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 11:20:37 +0100 Subject: [PATCH 26/65] fix tests --- Zend/tests/errmsg/errmsg_027.phpt | 2 +- Zend/zend_compile.c | 2 ++ .../tests/ReflectionClass_toString_001.phpt | 30 ++++++++++++++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Zend/tests/errmsg/errmsg_027.phpt b/Zend/tests/errmsg/errmsg_027.phpt index 3d96ec27b4d64..a30e1269453f9 100644 --- a/Zend/tests/errmsg/errmsg_027.phpt +++ b/Zend/tests/errmsg/errmsg_027.phpt @@ -13,4 +13,4 @@ class test { echo "Done\n"; ?> --EXPECTF-- -Fatal error: Class declarations may not be nested in %s on line %d +Fatal error: Class declarations may not be declared inside functions in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index a72d5dd8c144d..ae401fec2bddc 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -9239,6 +9239,8 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) /* Find an anon class name that is not in use yet. */ name = NULL; lcname = NULL; + ce->required_scope = NULL; + ce->lexical_scope = NULL; do { zend_tmp_string_release(name); zend_tmp_string_release(lcname); diff --git a/ext/reflection/tests/ReflectionClass_toString_001.phpt b/ext/reflection/tests/ReflectionClass_toString_001.phpt index fd5d83e917419..2a77633245d03 100644 --- a/ext/reflection/tests/ReflectionClass_toString_001.phpt +++ b/ext/reflection/tests/ReflectionClass_toString_001.phpt @@ -30,7 +30,7 @@ Class [ class ReflectionClass implements Stringable, Refle Property [ public string $name ] } - - Methods [64] { + - Methods [68] { Method [ private method __clone ] { - Parameters [0] { @@ -514,5 +514,33 @@ Class [ class ReflectionClass implements Stringable, Refle } - Return [ array ] } + + Method [ public method isInnerClass ] { + + - Parameters [0] { + } + - Return [ bool ] + } + + Method [ public method isPrivate ] { + + - Parameters [0] { + } + - Return [ bool ] + } + + Method [ public method isProtected ] { + + - Parameters [0] { + } + - Return [ bool ] + } + + Method [ public method isPublic ] { + + - Parameters [0] { + } + - Return [ bool ] + } } } From 6774e6161b1ea98d8eb1b7415284a56f787d4f7f Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 11:21:14 +0100 Subject: [PATCH 27/65] temporarily fix this test -- might want to undo this --- ext/reflection/tests/bug74454.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/reflection/tests/bug74454.phpt b/ext/reflection/tests/bug74454.phpt index 272409339c479..f1116becf6ce8 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" +ParseError: syntax error, unexpected token "if", expecting "class" From 9297a01add38c225fd78bf84e17115bd219636d8 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 12:38:37 +0100 Subject: [PATCH 28/65] clean up a bit and check readonly --- Zend/zend_compile.c | 2 +- Zend/zend_execute.c | 8 +++---- tests/classes/inner_classes/readonly_001.phpt | 23 +++++++++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 tests/classes/inner_classes/readonly_001.phpt diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ae401fec2bddc..ae2ba9b63863e 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -9199,7 +9199,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) decl->flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; } if (decl->attr & ZEND_ACC_READONLY) { - decl->flags |= ZEND_ACC_READONLY_CLASS & ZEND_ACC_NO_DYNAMIC_PROPERTIES; + decl->flags |= ZEND_ACC_READONLY_CLASS | ZEND_ACC_NO_DYNAMIC_PROPERTIES; } // configure for a nested class. This should only include: diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index d734b590bc3f7..36a9174c5dc0c 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1239,14 +1239,14 @@ static zend_always_inline bool zend_check_type_slow( zend_class_entry *scope = zend_get_executed_scope(); if (ce->required_scope_absolute && scope != ce->required_scope) { if (scope == NULL) { - zend_error(E_ERROR, "Private inner class %s cannot be used as a type declaration in the global scope", ce->name->val); + zend_error(E_ERROR, "Private inner class %s cannot be used as a type declaration in the global scope", ZSTR_VAL(ce->name)); } - zend_error(E_ERROR, "Private inner class %s cannot be used as a type declaration in the scope of %s", ce->name->val, scope->name->val); + zend_error(E_ERROR, "Private inner class %s cannot be used as a type declaration in the scope of %s", ZSTR_VAL(ce->name), ZSTR_VAL(scope->name)); } else if (scope == NULL) { - zend_error(E_ERROR, "Protected inner class %s cannot be used as a type declaration in the global scope", ce->name->val); + zend_error(E_ERROR, "Protected inner class %s cannot be used as a type declaration in the global scope", ZSTR_VAL(ce->name)); } else if (!instanceof_function(scope, ce->required_scope)) { - zend_error(E_ERROR, "Protected inner class %s cannot be used as a type declaration in the scope of %s", ce->name->val, scope->name->val); + zend_error(E_ERROR, "Protected inner class %s cannot be used as a type declaration in the scope of %s", ZSTR_VAL(ce->name), ZSTR_VAL(scope->name)); } } diff --git a/tests/classes/inner_classes/readonly_001.phpt b/tests/classes/inner_classes/readonly_001.phpt new file mode 100644 index 0000000000000..189c9bcb23b7d --- /dev/null +++ b/tests/classes/inner_classes/readonly_001.phpt @@ -0,0 +1,23 @@ +--TEST-- +readonly should work +--FILE-- +Inner(1)); +$foo->t = 42; +var_dump($foo); +?> +--EXPECTF-- +object(Outer:>Inner)#1 (1) { + ["t"]=> + int(1) +} + +Fatal error: Uncaught Error: Cannot modify readonly property Outer:>Inner::$t in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d From 441eb93a652c0603a5e7f021fc54536480462e24 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 15:30:19 +0100 Subject: [PATCH 29/65] handle visibility of methods --- Zend/zend_object_handlers.c | 11 ++++++++ .../classes/inner_classes/visibility_005.phpt | 27 ++++++++++++++++++ .../classes/inner_classes/visibility_006.phpt | 28 +++++++++++++++++++ .../classes/inner_classes/visibility_007.phpt | 27 ++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 tests/classes/inner_classes/visibility_005.phpt create mode 100644 tests/classes/inner_classes/visibility_006.phpt create mode 100644 tests/classes/inner_classes/visibility_007.phpt diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 9956c3f70e320..b3193f220b5e9 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1819,6 +1819,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string * /* Check access level */ if (fbc->op_array.fn_flags & (ZEND_ACC_CHANGED|ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) { scope = zend_get_executed_scope(); +check_lexical_scope: if (fbc->common.scope != scope) { if (fbc->op_array.fn_flags & ZEND_ACC_CHANGED) { @@ -1836,6 +1837,10 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string * if (zobj->ce->__call) { fbc = zend_get_user_call_function(zobj->ce, method_name); } else { + if (scope->lexical_scope) { + scope = scope->lexical_scope; + goto check_lexical_scope; + } zend_bad_method_call(fbc, method_name, scope); fbc = NULL; } @@ -1895,11 +1900,17 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st fbc = Z_FUNC_P(func); if (!(fbc->op_array.fn_flags & ZEND_ACC_PUBLIC)) { zend_class_entry *scope = zend_get_executed_scope(); +check_lexical_scope: if (UNEXPECTED(fbc->common.scope != scope)) { if (UNEXPECTED(fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) { zend_function *fallback_fbc = get_static_method_fallback(ce, function_name); if (!fallback_fbc) { + if (scope->lexical_scope) { + scope = scope->lexical_scope; + goto check_lexical_scope; + } + zend_bad_method_call(fbc, function_name, scope); } fbc = fallback_fbc; diff --git a/tests/classes/inner_classes/visibility_005.phpt b/tests/classes/inner_classes/visibility_005.phpt new file mode 100644 index 0000000000000..32737d6cbc5ee --- /dev/null +++ b/tests/classes/inner_classes/visibility_005.phpt @@ -0,0 +1,27 @@ +--TEST-- +accessing outer private methods +--FILE-- +Middle::test(); + $t = new Outer(); + $t->test(); + } + } + } +} +new Outer:>Middle:>Inner()->test(); +?> +--EXPECT-- +Outer:>Middle::test +Outer::test diff --git a/tests/classes/inner_classes/visibility_006.phpt b/tests/classes/inner_classes/visibility_006.phpt new file mode 100644 index 0000000000000..b5f1cc13a8a38 --- /dev/null +++ b/tests/classes/inner_classes/visibility_006.phpt @@ -0,0 +1,28 @@ +--TEST-- +scope doesn't bypass scope +--FILE-- +test(); + } + } + } +} +new Outer:>Middle:>Inner()->testit(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Call to undefined method Outer:>Middle:>Inner::test() in %s:%d +Stack trace: +#0 %s(%d): Outer:>Middle:>Inner->testit() +#1 {main} + thrown in %s on line %d diff --git a/tests/classes/inner_classes/visibility_007.phpt b/tests/classes/inner_classes/visibility_007.phpt new file mode 100644 index 0000000000000..5ed1ebcae5bca --- /dev/null +++ b/tests/classes/inner_classes/visibility_007.phpt @@ -0,0 +1,27 @@ +--TEST-- +accessing outer protected methods +--FILE-- +Middle::test(); + $t = new Outer(); + $t->test(); + } + } + } +} +new Outer:>Middle:>Inner()->test(); +?> +--EXPECT-- +Outer:>Middle::test +Outer::test From bcee5ab9d4920d97725a88343c0bce56b43fa0d0 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 15:30:43 +0100 Subject: [PATCH 30/65] just do not cache -- more trouble than it is worth right now --- Zend/zend_vm_def.h | 1 - Zend/zend_vm_execute.h | 3 --- 2 files changed, 4 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 1754c5b75bb41..c40f21c22b8ae 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1888,7 +1888,6 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S } } - CACHE_PTR(opline->extended_value, inner_ce); Z_CE_P(EX_VAR(opline->result.var)) = inner_ce; zend_string_release(full_class_name); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 5f25118af52d4..ce08a891e59de 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6701,7 +6701,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C } } - CACHE_PTR(opline->extended_value, inner_ce); Z_CE_P(EX_VAR(opline->result.var)) = inner_ce; zend_string_release(full_class_name); @@ -16334,7 +16333,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ } } - CACHE_PTR(opline->extended_value, inner_ce); Z_CE_P(EX_VAR(opline->result.var)) = inner_ce; zend_string_release(full_class_name); @@ -34085,7 +34083,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_ } } - CACHE_PTR(opline->extended_value, inner_ce); Z_CE_P(EX_VAR(opline->result.var)) = inner_ce; zend_string_release(full_class_name); From 4b847cde049e86be43c7b2ea0828eeeb3f63a5be Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 16:09:58 +0100 Subject: [PATCH 31/65] properly handle lexical scope --- 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 b3193f220b5e9..affe8203e51a5 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1837,7 +1837,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string * if (zobj->ce->__call) { fbc = zend_get_user_call_function(zobj->ce, method_name); } else { - if (scope->lexical_scope) { + if (scope && scope->lexical_scope) { scope = scope->lexical_scope; goto check_lexical_scope; } @@ -1906,7 +1906,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) { zend_function *fallback_fbc = get_static_method_fallback(ce, function_name); if (!fallback_fbc) { - if (scope->lexical_scope) { + if (scope && scope->lexical_scope) { scope = scope->lexical_scope; goto check_lexical_scope; } From 5a5e44b134bd54f9b9d1a59954bb847400cdcdb5 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 16:10:18 +0100 Subject: [PATCH 32/65] handle long names --- Zend/zend_vm_def.h | 5 +++++ Zend/zend_vm_execute.h | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index c40f21c22b8ae..816f7c1ccdd4a 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1856,6 +1856,11 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_S inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(ZSTR_LEN(outer_ce->name) + ZSTR_LEN(inner_class_name) + 2 > ZSTR_MAX_LEN)) { + zend_error(E_ERROR, "Class name is too long"); + HANDLE_EXCEPTION(); + } + full_class_name = zend_string_concat3( ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name), ":>", 2, diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index ce08a891e59de..86b9776665d4c 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6669,6 +6669,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_C inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(ZSTR_LEN(outer_ce->name) + ZSTR_LEN(inner_class_name) + 2 > ZSTR_MAX_LEN)) { + zend_error(E_ERROR, "Class name is too long"); + HANDLE_EXCEPTION(); + } + full_class_name = zend_string_concat3( ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name), ":>", 2, @@ -16301,6 +16306,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_ inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(ZSTR_LEN(outer_ce->name) + ZSTR_LEN(inner_class_name) + 2 > ZSTR_MAX_LEN)) { + zend_error(E_ERROR, "Class name is too long"); + HANDLE_EXCEPTION(); + } + full_class_name = zend_string_concat3( ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name), ":>", 2, @@ -34051,6 +34061,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_ inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(ZSTR_LEN(outer_ce->name) + ZSTR_LEN(inner_class_name) + 2 > ZSTR_MAX_LEN)) { + zend_error(E_ERROR, "Class name is too long"); + HANDLE_EXCEPTION(); + } + full_class_name = zend_string_concat3( ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name), ":>", 2, From f24caa36063d1f764a35e8d1dd0999ae0db91c53 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Fri, 14 Mar 2025 18:51:52 +0100 Subject: [PATCH 33/65] handle more visibility --- Zend/zend_object_handlers.c | 20 +++++++--- .../classes/inner_classes/visibility_008.phpt | 30 +++++++++++++++ .../classes/inner_classes/visibility_009.phpt | 38 +++++++++++++++++++ 3 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 tests/classes/inner_classes/visibility_008.phpt create mode 100644 tests/classes/inner_classes/visibility_009.phpt diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index affe8203e51a5..36f5a26ea2b41 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -381,6 +381,7 @@ static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *c if (flags & (ZEND_ACC_CHANGED|ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) { zend_class_entry *scope = get_fake_or_executed_scope(); +check_lexical_scope: if (property_info->ce != scope) { if (flags & ZEND_ACC_CHANGED) { zend_property_info *p = zend_get_parent_private_property(scope, ce, member); @@ -401,11 +402,11 @@ static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *c if (property_info->ce != ce) { goto dynamic; } else { - if (scope && scope->lexical_scope && scope->lexical_scope == ce) { - // Allow access to private properties from within the same outer class - goto found; - } wrong: + if (scope && scope->lexical_scope) { + scope = scope->lexical_scope; + goto check_lexical_scope; + } /* Information was available, but we were denied access. Error out. */ if (!silent) { zend_bad_property_access(property_info, ce, member); @@ -1819,6 +1820,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string * /* Check access level */ if (fbc->op_array.fn_flags & (ZEND_ACC_CHANGED|ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) { scope = zend_get_executed_scope(); + zend_class_entry *original_scope = scope; check_lexical_scope: if (fbc->common.scope != scope) { @@ -1841,7 +1843,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string * scope = scope->lexical_scope; goto check_lexical_scope; } - zend_bad_method_call(fbc, method_name, scope); + zend_bad_method_call(fbc, method_name, original_scope); fbc = NULL; } } @@ -1900,6 +1902,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st fbc = Z_FUNC_P(func); if (!(fbc->op_array.fn_flags & ZEND_ACC_PUBLIC)) { zend_class_entry *scope = zend_get_executed_scope(); + zend_class_entry *original_scope = scope; check_lexical_scope: if (UNEXPECTED(fbc->common.scope != scope)) { if (UNEXPECTED(fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) @@ -1911,7 +1914,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st goto check_lexical_scope; } - zend_bad_method_call(fbc, function_name, scope); + zend_bad_method_call(fbc, function_name, original_scope); } fbc = fallback_fbc; } @@ -1988,10 +1991,15 @@ ZEND_API zval *zend_std_get_static_property_with_info(zend_class_entry *ce, zend if (!(property_info->flags & ZEND_ACC_PUBLIC)) { zend_class_entry *scope = get_fake_or_executed_scope(); +check_lexical_scope: if (property_info->ce != scope) { if (UNEXPECTED(property_info->flags & ZEND_ACC_PRIVATE) || UNEXPECTED(!is_protected_compatible_scope(property_info->ce, scope))) { if (type != BP_VAR_IS) { + if (scope && scope->lexical_scope) { + scope = scope->lexical_scope; + goto check_lexical_scope; + } zend_bad_property_access(property_info, ce, property_name); } return NULL; diff --git a/tests/classes/inner_classes/visibility_008.phpt b/tests/classes/inner_classes/visibility_008.phpt new file mode 100644 index 0000000000000..6a5d8dadf94c5 --- /dev/null +++ b/tests/classes/inner_classes/visibility_008.phpt @@ -0,0 +1,30 @@ +--TEST-- +accessing sibling methods +--FILE-- +Middle::test(); + $t = new Outer(); + $t->test(); + } + } +} +new Other:>Inner()->test(); +?> +--EXPECT-- +Outer:>Middle::test +Outer::test diff --git a/tests/classes/inner_classes/visibility_009.phpt b/tests/classes/inner_classes/visibility_009.phpt new file mode 100644 index 0000000000000..4bf9ce96dd250 --- /dev/null +++ b/tests/classes/inner_classes/visibility_009.phpt @@ -0,0 +1,38 @@ +--TEST-- +deeply nested property visibility +--FILE-- +Middle::$j = 42); + $foo = new Outer(); + $foo->i = 42; + var_dump($foo); + $foo = new Outer:>Middle(); + $foo->i = 42; + var_dump($foo); + } + } + } +} +Outer:>Middle:>Inner::test(); +?> +--EXPECT-- +int(5) +int(42) +object(Outer)#1 (1) { + ["i":"Outer":private]=> + int(42) +} +object(Outer:>Middle)#2 (1) { + ["i":"Outer:>Middle":private]=> + int(42) +} From 20b26996946ba135b548ca1f4c13b5ea5f56a4c4 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sat, 15 Mar 2025 09:41:57 +0100 Subject: [PATCH 34/65] handle constructor visibility --- Zend/zend_object_handlers.c | 6 +++ tests/classes/inner_classes/enum_usage.phpt | 16 ++++++++ .../inner_classes/interface_usage.phpt | 21 ++++++++++ tests/classes/inner_classes/trait_usage.phpt | 24 +++++++++++ .../classes/inner_classes/visibility_010.phpt | 41 +++++++++++++++++++ 5 files changed, 108 insertions(+) create mode 100644 tests/classes/inner_classes/enum_usage.phpt create mode 100644 tests/classes/inner_classes/interface_usage.phpt create mode 100644 tests/classes/inner_classes/trait_usage.phpt create mode 100644 tests/classes/inner_classes/visibility_010.phpt diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 36f5a26ea2b41..9a55c0b6e2168 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -2080,9 +2080,15 @@ ZEND_API zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */ if (constructor) { if (UNEXPECTED(!(constructor->op_array.fn_flags & ZEND_ACC_PUBLIC))) { zend_class_entry *scope = get_fake_or_executed_scope(); +check_lexical_scope: if (UNEXPECTED(constructor->common.scope != scope)) { if (UNEXPECTED(constructor->op_array.fn_flags & ZEND_ACC_PRIVATE) || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(constructor), scope))) { + if (scope && scope->lexical_scope) { + scope = scope->lexical_scope; + goto check_lexical_scope; + } + zend_bad_constructor_call(constructor, scope); zend_object_store_ctor_failed(zobj); constructor = NULL; diff --git a/tests/classes/inner_classes/enum_usage.phpt b/tests/classes/inner_classes/enum_usage.phpt new file mode 100644 index 0000000000000..d96533aa54a38 --- /dev/null +++ b/tests/classes/inner_classes/enum_usage.phpt @@ -0,0 +1,16 @@ +--TEST-- +usage in an enum +--FILE-- +Inner()); +var_dump(class_exists(Outer:>Inner::class)); +?> +--EXPECT-- +object(Outer:>Inner)#1 (0) { +} +bool(true) diff --git a/tests/classes/inner_classes/interface_usage.phpt b/tests/classes/inner_classes/interface_usage.phpt new file mode 100644 index 0000000000000..2d3a071531d0a --- /dev/null +++ b/tests/classes/inner_classes/interface_usage.phpt @@ -0,0 +1,21 @@ +--TEST-- +usage in an interface +--FILE-- +Inner()); + +class Foo implements Outer {} + +var_dump(class_exists(Outer:>Inner::class)); +var_dump(class_exists(Foo:>Inner::class)); +?> +--EXPECT-- +object(Outer:>Inner)#1 (0) { +} +bool(true) +bool(false) diff --git a/tests/classes/inner_classes/trait_usage.phpt b/tests/classes/inner_classes/trait_usage.phpt new file mode 100644 index 0000000000000..1511b8a642214 --- /dev/null +++ b/tests/classes/inner_classes/trait_usage.phpt @@ -0,0 +1,24 @@ +--TEST-- +usage inside a trait +--FILE-- +Inner()); + +class Foo { + use Outer; +} + +var_dump(class_exists(Outer:>Inner::class)); +var_dump(class_exists(Foo:>Inner::class)); + +?> +--EXPECT-- +object(Outer:>Inner)#1 (0) { +} +bool(true) +bool(false) diff --git a/tests/classes/inner_classes/visibility_010.phpt b/tests/classes/inner_classes/visibility_010.phpt new file mode 100644 index 0000000000000..d70478ba09a57 --- /dev/null +++ b/tests/classes/inner_classes/visibility_010.phpt @@ -0,0 +1,41 @@ +--TEST-- +constructors +--FILE-- +Builder $builder) { + $this->name = $builder->name; + $this->email = $builder->email; + } + + public readonly final class Builder { + public function __construct(public private(set) string|null $name = null, public private(set) string|null $email = null) {} + + public function withEmail(string $email): self { + return new self($this->name, $email); + } + + public function withName(string $name): self { + return new self($name, $this->email); + } + + public function build(): User { + return new User($this); + } + } +} + +$user = new User:>Builder()->withName('Rob')->withEmail('rob@example.com')->build(); +var_dump($user); +?> +--EXPECT-- +object(User)#2 (2) { + ["name"]=> + string(3) "Rob" + ["email"]=> + string(15) "rob@example.com" +} From e4d3e6265741ab39f9fc5d09dd453db225cf167d Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sat, 15 Mar 2025 11:09:40 +0100 Subject: [PATCH 35/65] prevent static access --- Zend/zend_compile.c | 6 ++++-- Zend/zend_compile.h | 1 + .../inner_classes/simple_declaration_004.phpt | 14 ++++++-------- .../classes/inner_classes/static_resolution.phpt | 16 ++++++++++++++++ 4 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 tests/classes/inner_classes/static_resolution.phpt diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ae2ba9b63863e..86443e65a216f 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2933,7 +2933,7 @@ static void zend_compile_inner_class_ref(znode *result, zend_ast *ast, uint32_t if (outer_class->kind == ZEND_AST_INNER_CLASS) { zend_compile_inner_class_ref(&outer_node, outer_class, fetch_flags); } else { - zend_compile_class_ref(&outer_node, outer_class, fetch_flags); + zend_compile_class_ref(&outer_node, outer_class, fetch_flags | ZEND_FETCH_CLASS_OUTER); } if (inner_class->kind == ZEND_AST_ZVAL && Z_TYPE_P(zend_ast_get_zval(inner_class)) == IS_STRING) { @@ -2999,10 +2999,12 @@ static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t f if (ZEND_FETCH_CLASS_DEFAULT == fetch_type) { result->op_type = IS_CONST; ZVAL_STR(&result->u.constant, zend_resolve_class_name_ast(name_ast)); + } else if (fetch_flags & ZEND_FETCH_CLASS_OUTER && fetch_type == ZEND_FETCH_CLASS_STATIC) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use the static modifier on an inner class"); } else { zend_ensure_valid_class_fetch_type(fetch_type); result->op_type = IS_UNUSED; - result->u.op.num = fetch_type | fetch_flags; + result->u.op.num = fetch_type | (fetch_flags & ~ZEND_FETCH_CLASS_OUTER); } } /* }}} */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 0d3ccc2e066b4..f2a560359c5f1 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1021,6 +1021,7 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); #define ZEND_FETCH_CLASS_AUTO 4 #define ZEND_FETCH_CLASS_INTERFACE 5 #define ZEND_FETCH_CLASS_TRAIT 6 +#define ZEND_FETCH_CLASS_OUTER 7 #define ZEND_FETCH_CLASS_MASK 0x0f #define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80 #define ZEND_FETCH_CLASS_SILENT 0x0100 diff --git a/tests/classes/inner_classes/simple_declaration_004.phpt b/tests/classes/inner_classes/simple_declaration_004.phpt index 54611341343e6..898045a3ee606 100644 --- a/tests/classes/inner_classes/simple_declaration_004.phpt +++ b/tests/classes/inner_classes/simple_declaration_004.phpt @@ -6,9 +6,6 @@ scope resolution access class Outer { public class Middle { } - public static function testStatic(): self:>Middle { - return new static:>Middle(); - } public static function testSelf(): self:>Middle { return new self:>Middle(); } @@ -21,12 +18,15 @@ class Outer2 extends Outer { public static function testParent(): parent:>Middle { return new parent:>Middle(); } + + public static function testSelf(): self:>Middle { + return new self:>Middle(); + } } -var_dump(Outer::testStatic()); var_dump(Outer::testSelf()); var_dump(Outer2::testParent()); -var_dump(Outer2::testStatic()); +var_dump(Outer2::testSelf()); var_dump(Outer2::testSelf()); ?> @@ -35,9 +35,7 @@ object(Outer:>Middle)#1 (0) { } object(Outer:>Middle)#1 (0) { } -object(Outer:>Middle)#1 (0) { -} object(Outer2:>Middle)#1 (0) { } -object(Outer:>Middle)#1 (0) { +object(Outer2:>Middle)#1 (0) { } diff --git a/tests/classes/inner_classes/static_resolution.phpt b/tests/classes/inner_classes/static_resolution.phpt new file mode 100644 index 0000000000000..e67ed0cf65e6a --- /dev/null +++ b/tests/classes/inner_classes/static_resolution.phpt @@ -0,0 +1,16 @@ +--TEST-- +static resolution +--FILE-- +Inner(); + } +} +var_dump(new Outer()->test()); +?> +--EXPECTF-- +Fatal error: Cannot use the static modifier on an inner class in %s on line %d From 609ce36ffb1dac291db6576cf1bb38c340246d3a Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Mon, 24 Mar 2025 22:20:41 +0100 Subject: [PATCH 36/65] remove T_INNER_REF --- Zend/zend_language_parser.y | 12 +----------- Zend/zend_language_scanner.l | 4 ---- ext/tokenizer/tokenizer_data.c | 1 - ext/tokenizer/tokenizer_data.stub.php | 5 ----- ext/tokenizer/tokenizer_data_arginfo.h | 1 - 5 files changed, 1 insertion(+), 22 deletions(-) diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 68f4752774fa1..0328e6b367e8c 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -232,7 +232,6 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_DOLLAR_OPEN_CURLY_BRACES "'${'" %token T_CURLY_OPEN "'{$'" %token T_PAAMAYIM_NEKUDOTAYIM "'::'" -%token T_INNER_REF "':>'" %token T_NS_SEPARATOR "'\\'" %token T_ELLIPSIS "'...'" %token T_COALESCE "'??'" @@ -877,14 +876,7 @@ type_expr_without_static: type_without_static: T_ARRAY { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_ARRAY); } | T_CALLABLE { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_CALLABLE); } - | inner_type_without_static { $$ = $1; } -; - -inner_type_without_static: - inner_type_without_static T_INNER_REF name - { $$ = zend_ast_create(ZEND_AST_INNER_CLASS, $1, $3); } - | name - { $$ = $1; } + | name { $$ = $1; } ; union_type_without_static_element: @@ -1433,8 +1425,6 @@ class_name: { zval zv; ZVAL_INTERNED_STR(&zv, ZSTR_KNOWN(ZEND_STR_STATIC)); $$ = zend_ast_create_zval_ex(&zv, ZEND_NAME_NOT_FQ); } | name { $$ = $1; } - | class_name T_INNER_REF name - { $$ = zend_ast_create(ZEND_AST_INNER_CLASS, $1, $3); } ; class_name_reference: diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 729c096976afb..4c883b81c5f7d 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -1601,10 +1601,6 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_ RETURN_TOKEN(T_PAAMAYIM_NEKUDOTAYIM); } -":>" { - RETURN_TOKEN(T_INNER_REF); -} - "..." { RETURN_TOKEN(T_ELLIPSIS); } diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index 0f1bee1ee37bb..a1e131032bcfb 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -168,7 +168,6 @@ char *get_token_type_name(int token_type) case T_DOLLAR_OPEN_CURLY_BRACES: return "T_DOLLAR_OPEN_CURLY_BRACES"; case T_CURLY_OPEN: return "T_CURLY_OPEN"; case T_PAAMAYIM_NEKUDOTAYIM: return "T_DOUBLE_COLON"; - case T_INNER_REF: return "T_INNER_REF"; case T_NS_SEPARATOR: return "T_NS_SEPARATOR"; case T_ELLIPSIS: return "T_ELLIPSIS"; case T_COALESCE: return "T_COALESCE"; diff --git a/ext/tokenizer/tokenizer_data.stub.php b/ext/tokenizer/tokenizer_data.stub.php index 089bd5736f9a7..c1e1fd254dfaa 100644 --- a/ext/tokenizer/tokenizer_data.stub.php +++ b/ext/tokenizer/tokenizer_data.stub.php @@ -717,11 +717,6 @@ * @cvalue T_PAAMAYIM_NEKUDOTAYIM */ const T_PAAMAYIM_NEKUDOTAYIM = UNKNOWN; -/** - * @var int - * @cvalue T_INNER_REF - */ -const T_INNER_REF = UNKNOWN; /** * @var int * @cvalue T_NS_SEPARATOR diff --git a/ext/tokenizer/tokenizer_data_arginfo.h b/ext/tokenizer/tokenizer_data_arginfo.h index 3df94973e6cc2..9c488d19f1890 100644 --- a/ext/tokenizer/tokenizer_data_arginfo.h +++ b/ext/tokenizer/tokenizer_data_arginfo.h @@ -146,7 +146,6 @@ static void register_tokenizer_data_symbols(int module_number) REGISTER_LONG_CONSTANT("T_DOLLAR_OPEN_CURLY_BRACES", T_DOLLAR_OPEN_CURLY_BRACES, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_CURLY_OPEN", T_CURLY_OPEN, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_PAAMAYIM_NEKUDOTAYIM", T_PAAMAYIM_NEKUDOTAYIM, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("T_INNER_REF", T_INNER_REF, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_NS_SEPARATOR", T_NS_SEPARATOR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_ELLIPSIS", T_ELLIPSIS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_COALESCE", T_COALESCE, CONST_PERSISTENT); From b2bb823e6d53e7bc561ddde19c646782ad1c1d00 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Mon, 24 Mar 2025 22:21:36 +0100 Subject: [PATCH 37/65] allow inner classes to use \\ now --- Zend/zend_compile.c | 5 +- Zend/zend_compile.h | 1 + Zend/zend_execute_API.c | 46 +++++++++++++++ Zend/zend_namespaces.c | 123 ++++++++++++++++++++++++++++++++++++++++ Zend/zend_namespaces.h | 29 ++++++++++ configure.ac | 1 + main/main.c | 4 ++ 7 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 Zend/zend_namespaces.c create mode 100644 Zend/zend_namespaces.h diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 86443e65a216f..c737bc9434daa 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -38,6 +38,7 @@ #include "zend_call_stack.h" #include "zend_frameless_function.h" #include "zend_property_hooks.h" +#include "zend_namespaces.h" #define SET_NODE(target, src) do { \ target ## _type = (src)->op_type; \ @@ -9188,7 +9189,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) // rename the inner class so we may reference it by name name = zend_string_concat3( ZSTR_VAL(CG(active_class_entry)->name), ZSTR_LEN(CG(active_class_entry)->name), - ":>", 2, + "\\", 1, ZSTR_VAL(unqualified_name), ZSTR_LEN(unqualified_name) ); @@ -9222,7 +9223,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) } else { name = zend_prefix_with_ns(unqualified_name); ce->required_scope = NULL; - ce->lexical_scope = NULL; + ce->lexical_scope = zend_resolve_namespace(FC(current_namespace)); } name = zend_new_interned_string(name); lcname = zend_string_tolower(name); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index f2a560359c5f1..916c0154371b0 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1062,6 +1062,7 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); #define ZEND_INTERNAL_CLASS 1 #define ZEND_USER_CLASS 2 +#define ZEND_NAMESPACE_CLASS 4 #define ZEND_EVAL (1<<0) #define ZEND_INCLUDE (1<<1) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 1f55521fb72f1..75046719cbb4a 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1166,6 +1166,27 @@ ZEND_API bool zend_is_valid_class_name(zend_string *name) { return 1; } +static zend_string *get_namespace_from_scope(const zend_class_entry *scope) { + while (scope && scope->lexical_scope && scope->type != ZEND_NAMESPACE_CLASS) { + scope = scope->lexical_scope; + } + return scope->name; +} + +static zend_string *get_scoped_name(const zend_string *ns, zend_string *name) { + // remove the matching prefix from name + name = zend_string_tolower(name); + if (ns && ZSTR_LEN(ns) && ZSTR_LEN(name) > ZSTR_LEN(ns) + 1 && + memcmp(ZSTR_VAL(name), ZSTR_VAL(ns), ZSTR_LEN(ns)) == 0 && + ZSTR_VAL(name)[ZSTR_LEN(ns)] == '\\') { + zend_string *ret = zend_string_init(ZSTR_VAL(name) + ZSTR_LEN(ns) + 1, ZSTR_LEN(name) - ZSTR_LEN(ns) - 1, 0); + zend_string_release(name); + return ret; + } + zend_string_release(name); + return name; +} + ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *key, uint32_t flags) /* {{{ */ { zend_class_entry *ce = NULL; @@ -1182,6 +1203,31 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * } } + if (!zend_is_compiling()) { + const zend_class_entry *scope = zend_get_executed_scope(); + if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) { + zend_string *ns_name = get_namespace_from_scope(scope); + zend_string *scoped_name = get_scoped_name(ns_name, name); + while (scope->type != ZEND_NAMESPACE_CLASS) { + zend_string *try_name = zend_string_concat3(ZSTR_VAL(scope->name), ZSTR_LEN(scope->name), "\\", 1, ZSTR_VAL(scoped_name), ZSTR_LEN(scoped_name)); + lc_name = zend_string_tolower(try_name); + ce = zend_hash_find_ptr(EG(class_table), lc_name); + if (ce) { + zend_string_release(lc_name); + zend_string_release(scoped_name); + zend_string_release(ns_name); + zend_string_release(try_name); + return ce; + } + scope = scope->lexical_scope; + zend_string_release(lc_name); + zend_string_release(try_name); + } + zend_string_release(ns_name); + zend_string_release(scoped_name); + } + } + if (key) { lc_name = key; } else { diff --git a/Zend/zend_namespaces.c b/Zend/zend_namespaces.c new file mode 100644 index 0000000000000..6981bc035f1c7 --- /dev/null +++ b/Zend/zend_namespaces.c @@ -0,0 +1,123 @@ +/* ++----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Rob Landers | + | | + +----------------------------------------------------------------------+ +*/ + +#include "zend_namespaces.h" + +#include + +#include "zend_API.h" +#include "zend_hash.h" + +static zend_class_entry *global_namespace = NULL; +static HashTable namespaces; + +static zend_class_entry *create_namespace(zend_string *name) { + zend_class_entry *ns = pemalloc(sizeof(zend_class_entry), 1); + memset(ns, 0, sizeof(zend_class_entry)); + zend_initialize_class_data(ns, 1); + ns->type = ZEND_NAMESPACE_CLASS; + + zend_string *interned_name = zend_new_interned_string(zend_string_copy(name)); + ns->name = interned_name; + + return ns; +} + +static zend_class_entry *insert_namespace(const zend_string *name) { + zend_class_entry *ns = NULL; + zend_class_entry *parent_ns = global_namespace; + zend_string *part = NULL; + const char *start = ZSTR_VAL(name); + const char *end = start + ZSTR_LEN(name); + const char *pos = start; + size_t len = 0; + + smart_str current_ns = {0}; + + while (pos <= end) { + if (pos == end || *pos == '\\') { + len = pos - start; + part = zend_string_init(start, len, 0); + + if (current_ns.s) { + smart_str_appendc(¤t_ns, '\\'); + } + smart_str_appendl(¤t_ns, ZSTR_VAL(part), ZSTR_LEN(part)); + smart_str_0(¤t_ns); + + zend_string *needle = zend_string_init(ZSTR_VAL(current_ns.s), ZSTR_LEN(current_ns.s), 0); + ns = zend_hash_find_ptr(&namespaces, needle); + + if (!ns) { + ns = create_namespace(needle); + ns->parent = parent_ns; + zend_hash_add_ptr(&namespaces, current_ns.s, ns); + } + + zend_string_release(part); + zend_string_release(needle); + + parent_ns = ns; + start = pos + 1; + } + pos++; + } + + smart_str_free(¤t_ns); + + return ns; +} + +zend_class_entry *zend_resolve_namespace(zend_string *name) { + if (global_namespace == NULL) { + global_namespace = create_namespace(zend_empty_string); + zend_hash_init(&namespaces, 8, NULL, ZEND_CLASS_DTOR, 1); + zend_hash_add_ptr(&namespaces, zend_empty_string, global_namespace); + } + + if (name == NULL || ZSTR_LEN(name) == 0) { + return global_namespace; + } + + zend_string *lc_name = zend_string_tolower(name); + zend_class_entry *ns = zend_hash_find_ptr(&namespaces, lc_name); + + if (!ns) { + ns = insert_namespace(lc_name); + } + + zend_string_release(lc_name); + + return ns; +} + +void zend_destroy_namespaces() { + if (global_namespace == NULL) { + return; + } + + const zend_class_entry *ns = NULL; + ZEND_HASH_FOREACH_PTR(&namespaces, ns) { + zend_string_release(ns->name); + } ZEND_HASH_FOREACH_END(); + + zend_hash_destroy(&namespaces); + zend_string_release(global_namespace->name); + pefree(global_namespace, 1); +} diff --git a/Zend/zend_namespaces.h b/Zend/zend_namespaces.h new file mode 100644 index 0000000000000..4879fd7039119 --- /dev/null +++ b/Zend/zend_namespaces.h @@ -0,0 +1,29 @@ +/* ++----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Rob Landers | + | | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_NAMESPACES_H +#define ZEND_NAMESPACES_H + +#include "zend.h" +#include "zend_compile.h" + +zend_class_entry *zend_resolve_namespace(zend_string *name); +void zend_destroy_namespaces(void); + +#endif //ZEND_NAMESPACES_H diff --git a/configure.ac b/configure.ac index 01d9ded69b920..e1f99ab8e287d 100644 --- a/configure.ac +++ b/configure.ac @@ -1757,6 +1757,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([ zend_opcode.c zend_operators.c zend_property_hooks.c + zend_namespaces.c zend_ptr_stack.c zend_signal.c zend_smart_str.c diff --git a/main/main.c b/main/main.c index 415cb02185e94..82f3960d36754 100644 --- a/main/main.c +++ b/main/main.c @@ -66,6 +66,8 @@ #include #endif +#include + #include "zend_compile.h" #include "zend_execute.h" #include "zend_highlight.h" @@ -1966,6 +1968,8 @@ void php_request_shutdown(void *dummy) zend_post_deactivate_modules(); } zend_end_try(); + zend_destroy_namespaces(); + /* 12. SAPI related shutdown*/ zend_try { sapi_deactivate_module(); From e17d677f585b5f87b70f75af376dbca648bd194e Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Mon, 24 Mar 2025 22:39:42 +0100 Subject: [PATCH 38/65] fix prototype issue --- Zend/zend_namespaces.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_namespaces.c b/Zend/zend_namespaces.c index 6981bc035f1c7..38b3ab636a9b2 100644 --- a/Zend/zend_namespaces.c +++ b/Zend/zend_namespaces.c @@ -107,7 +107,7 @@ zend_class_entry *zend_resolve_namespace(zend_string *name) { return ns; } -void zend_destroy_namespaces() { +void zend_destroy_namespaces(void) { if (global_namespace == NULL) { return; } From 63745a5bc8e4670f8a13f41a3605c83a89d1fe23 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Mon, 24 Mar 2025 22:40:00 +0100 Subject: [PATCH 39/65] defer compiling inner classes --- Zend/zend_compile.c | 50 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c737bc9434daa..8b1ae73c76e04 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -9094,10 +9094,9 @@ static void zend_compile_use_trait(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_implements(zend_ast *ast) /* {{{ */ +static void zend_compile_implements(zend_ast *ast, zend_class_entry *ce) /* {{{ */ { zend_ast_list *list = zend_ast_get_list(ast); - zend_class_entry *ce = CG(active_class_entry); zend_class_name *interface_names; uint32_t i; @@ -9155,6 +9154,17 @@ static void zend_compile_enum_backing_type(zend_class_entry *ce, zend_ast *enum_ zend_type_release(type, 0); } +HashTable *inner_class_queue = NULL; + +static void zend_defer_class_decl(zend_ast *ast) { + if (inner_class_queue == NULL) { + ALLOC_HASHTABLE(inner_class_queue); + zend_hash_init(inner_class_queue, 8, NULL, ZVAL_PTR_DTOR, 0); + } + + zend_hash_next_index_insert_ptr(inner_class_queue, ast); +} + static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) /* {{{ */ { zend_ast_decl *decl = (zend_ast_decl *) ast; @@ -9285,16 +9295,16 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) zend_resolve_const_class_name_reference(extends_ast, "class name"); } + if (implements_ast) { + zend_compile_implements(implements_ast, ce); + } + CG(active_class_entry) = ce; if (decl->child[3]) { zend_compile_attributes(&ce->attributes, decl->child[3], 0, ZEND_ATTRIBUTE_TARGET_CLASS, 0); } - if (implements_ast) { - zend_compile_implements(implements_ast); - } - if (ce->ce_flags & ZEND_ACC_ENUM) { if (enum_backing_type_ast != NULL) { zend_compile_enum_backing_type(ce, enum_backing_type_ast); @@ -9312,8 +9322,6 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) zend_verify_abstract_class(ce); } - CG(active_class_entry) = original_ce; - if (toplevel) { ce->ce_flags |= ZEND_ACC_TOP_LEVEL; } @@ -9334,7 +9342,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) && !zend_compile_ignore_class(parent_ce, ce->info.user.filename)) { if (zend_try_early_bind(ce, parent_ce, lcname, NULL)) { zend_string_release(lcname); - return; + goto compile_inner_classes; } } } else if (EXPECTED(zend_hash_add_ptr(CG(class_table), lcname, ce) != NULL)) { @@ -9343,7 +9351,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) zend_inheritance_check_override(ce); ce->ce_flags |= ZEND_ACC_LINKED; zend_observer_class_linked_notify(ce, lcname); - return; + goto compile_inner_classes; } else { goto link_unbound; } @@ -9413,6 +9421,24 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) opline->result.opline_num = -1; } } + compile_inner_classes: + + if (inner_class_queue == NULL) { + CG(active_class_entry) = original_ce; + return; + } + + HashTable *queue = inner_class_queue; + inner_class_queue = NULL; + + ZEND_HASH_FOREACH_PTR(queue, ast) { + zend_compile_class_decl(NULL, ast, 0); + } ZEND_HASH_FOREACH_END(); + + CG(active_class_entry) = original_ce; + + zend_hash_destroy(queue); + FREE_HASHTABLE(queue); } /* }}} */ @@ -11712,6 +11738,10 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ zend_compile_use(ast); break; case ZEND_AST_CONST_DECL: + if (CG(active_class_entry)) { + zend_defer_class_decl(ast); + break; + } zend_compile_const_decl(ast); break; case ZEND_AST_NAMESPACE: From 7a16a09b8f32f251bbd6d82e984e817125268ea5 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Mon, 24 Mar 2025 22:41:44 +0100 Subject: [PATCH 40/65] handle nesting classes in functions --- Zend/zend_compile.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 8b1ae73c76e04..c68d86d2e5eda 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -9157,6 +9157,12 @@ static void zend_compile_enum_backing_type(zend_class_entry *ce, zend_ast *enum_ HashTable *inner_class_queue = NULL; static void zend_defer_class_decl(zend_ast *ast) { + ZEND_ASSERT(CG(active_class_entry)); + + if (CG(active_op_array)->function_name) { + zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be declared inside functions"); + } + if (inner_class_queue == NULL) { ALLOC_HASHTABLE(inner_class_queue); zend_hash_init(inner_class_queue, 8, NULL, ZVAL_PTR_DTOR, 0); From 1f2ddb2a66a49aacbd30573cb7e00eb4a9e27a85 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 09:57:47 +0100 Subject: [PATCH 41/65] update tests --- tests/classes/.idea/.gitignore | 8 ++++ tests/classes/.idea/classes.iml | 8 ++++ tests/classes/.idea/deployment.xml | 14 +++++++ tests/classes/.idea/misc.xml | 7 ++++ tests/classes/.idea/modules.xml | 8 ++++ tests/classes/.idea/php.xml | 22 ++++++++++ tests/classes/.idea/vcs.xml | 6 +++ .../inner_classes/access_modifiers_007.phpt | 8 ++-- tests/classes/inner_classes/autoload_001.phpt | 6 +-- tests/classes/inner_classes/autoload_002.phpt | 11 +++-- tests/classes/inner_classes/enum_usage.phpt | 6 +-- tests/classes/inner_classes/errors_001.phpt | 7 +++- tests/classes/inner_classes/errors_002.phpt | 7 +++- tests/classes/inner_classes/inheritance.phpt | 10 +++-- .../inner_classes/interface_usage.phpt | 8 ++-- tests/classes/inner_classes/readonly_001.phpt | 6 +-- .../classes/inner_classes/reflection_001.phpt | 6 +-- .../inner_classes/return_types_001.phpt | 8 ++-- .../inner_classes/return_types_002.phpt | 16 ++++--- .../inner_classes/return_types_003.phpt | 14 +++---- .../inner_classes/return_types_004.phpt | 8 ++-- .../inner_classes/return_types_005.phpt | 8 ++-- .../inner_classes/return_types_006.phpt | 6 +-- .../inner_classes/simple_declaration_001.phpt | 8 ++-- .../inner_classes/simple_declaration_003.phpt | 4 +- .../inner_classes/simple_declaration_004.phpt | 22 +++++----- .../inner_classes/simple_declaration_005.phpt | 42 +++++++++++++++++++ .../inner_classes/static_resolution.phpt | 16 ------- .../inner_classes/static_variables.phpt | 16 +++---- tests/classes/inner_classes/trait_usage.phpt | 8 ++-- .../classes/inner_classes/visibility_001.phpt | 6 +-- .../classes/inner_classes/visibility_002.phpt | 6 +-- .../classes/inner_classes/visibility_003.phpt | 6 +-- .../classes/inner_classes/visibility_004.phpt | 6 +-- .../classes/inner_classes/visibility_005.phpt | 6 +-- .../classes/inner_classes/visibility_006.phpt | 6 +-- .../classes/inner_classes/visibility_007.phpt | 6 +-- .../classes/inner_classes/visibility_008.phpt | 6 +-- .../classes/inner_classes/visibility_009.phpt | 10 ++--- .../classes/inner_classes/visibility_010.phpt | 4 +- 40 files changed, 250 insertions(+), 136 deletions(-) create mode 100644 tests/classes/.idea/.gitignore create mode 100644 tests/classes/.idea/classes.iml create mode 100644 tests/classes/.idea/deployment.xml create mode 100644 tests/classes/.idea/misc.xml create mode 100644 tests/classes/.idea/modules.xml create mode 100644 tests/classes/.idea/php.xml create mode 100644 tests/classes/.idea/vcs.xml create mode 100644 tests/classes/inner_classes/simple_declaration_005.phpt delete mode 100644 tests/classes/inner_classes/static_resolution.phpt diff --git a/tests/classes/.idea/.gitignore b/tests/classes/.idea/.gitignore new file mode 100644 index 0000000000000..13566b81b018a --- /dev/null +++ b/tests/classes/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/tests/classes/.idea/classes.iml b/tests/classes/.idea/classes.iml new file mode 100644 index 0000000000000..bf4c9d396a05d --- /dev/null +++ b/tests/classes/.idea/classes.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/tests/classes/.idea/deployment.xml b/tests/classes/.idea/deployment.xml new file mode 100644 index 0000000000000..a1b58348df6f7 --- /dev/null +++ b/tests/classes/.idea/deployment.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/classes/.idea/misc.xml b/tests/classes/.idea/misc.xml new file mode 100644 index 0000000000000..d7a613f20d021 --- /dev/null +++ b/tests/classes/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/tests/classes/.idea/modules.xml b/tests/classes/.idea/modules.xml new file mode 100644 index 0000000000000..02630dad86b5a --- /dev/null +++ b/tests/classes/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/tests/classes/.idea/php.xml b/tests/classes/.idea/php.xml new file mode 100644 index 0000000000000..c41a634129307 --- /dev/null +++ b/tests/classes/.idea/php.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/classes/.idea/vcs.xml b/tests/classes/.idea/vcs.xml new file mode 100644 index 0000000000000..c8ade07fc487e --- /dev/null +++ b/tests/classes/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tests/classes/inner_classes/access_modifiers_007.phpt b/tests/classes/inner_classes/access_modifiers_007.phpt index d1177412939f1..88b9071b958cc 100644 --- a/tests/classes/inner_classes/access_modifiers_007.phpt +++ b/tests/classes/inner_classes/access_modifiers_007.phpt @@ -7,21 +7,21 @@ class Outer { public abstract class Inner {} } -class Extended extends Outer:>Inner {} +class Extended extends Outer\Inner {} $extended = new Extended(); var_dump($extended); -$reflection = new ReflectionClass('Outer:>Inner'); +$reflection = new ReflectionClass('Outer\Inner'); var_dump($reflection->isAbstract()); -new Outer:>Inner(); +new Outer\Inner(); ?> --EXPECTF-- object(Extended)#1 (0) { } bool(true) -Fatal error: Uncaught Error: Cannot instantiate abstract class Outer:>Inner in %s:%d +Fatal error: Uncaught Error: Cannot instantiate abstract class Outer\Inner in %s:%d Stack trace: #0 {main} thrown in %s on line %d diff --git a/tests/classes/inner_classes/autoload_001.phpt b/tests/classes/inner_classes/autoload_001.phpt index eef4cdfa5de09..dc18c02c8b9de 100644 --- a/tests/classes/inner_classes/autoload_001.phpt +++ b/tests/classes/inner_classes/autoload_001.phpt @@ -3,13 +3,13 @@ ensure autoloading works --FILE-- Point(1, 2); +$point = new inner_classes\Point(1, 2); echo $point->x, ' ', $point->y, "\n"; ?> --EXPECT-- -autoload(inner_classes) +autoload(inner_classes\Point) 1 2 diff --git a/tests/classes/inner_classes/autoload_002.phpt b/tests/classes/inner_classes/autoload_002.phpt index f2cbd1fc6cc74..8365942a86db2 100644 --- a/tests/classes/inner_classes/autoload_002.phpt +++ b/tests/classes/inner_classes/autoload_002.phpt @@ -3,14 +3,17 @@ ensure private autoloading works --FILE-- Line(); +$line = new inner_classes\Line(); var_dump($line); ?> --EXPECTF-- -autoload(inner_classes) +autoload(inner_classes\Line) -Fatal error: Cannot access private inner class 'inner_classes:>Line' in %s +Fatal error: Uncaught Error: Cannot instantiate class inner_classes\Line from the global scope in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/tests/classes/inner_classes/enum_usage.phpt b/tests/classes/inner_classes/enum_usage.phpt index d96533aa54a38..00b2c5f755a55 100644 --- a/tests/classes/inner_classes/enum_usage.phpt +++ b/tests/classes/inner_classes/enum_usage.phpt @@ -7,10 +7,10 @@ enum Outer { class Inner {} } -var_dump(new Outer:>Inner()); -var_dump(class_exists(Outer:>Inner::class)); +var_dump(new Outer\Inner()); +var_dump(class_exists(Outer\Inner::class)); ?> --EXPECT-- -object(Outer:>Inner)#1 (0) { +object(Outer\Inner)#1 (0) { } bool(true) diff --git a/tests/classes/inner_classes/errors_001.phpt b/tests/classes/inner_classes/errors_001.phpt index f4817e95351ce..d03109ea5af51 100644 --- a/tests/classes/inner_classes/errors_001.phpt +++ b/tests/classes/inner_classes/errors_001.phpt @@ -3,7 +3,10 @@ no outer class --FILE-- Inner(); +new Outer\Inner(); ?> --EXPECTF-- -Fatal error: Outer class 'Outer' not found for inner class Outer:>Inner in %s on line %d +Fatal error: Uncaught Error: Class "Outer\Inner" not found in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/tests/classes/inner_classes/errors_002.phpt b/tests/classes/inner_classes/errors_002.phpt index c9e1c08147675..883310c6705d0 100644 --- a/tests/classes/inner_classes/errors_002.phpt +++ b/tests/classes/inner_classes/errors_002.phpt @@ -6,7 +6,10 @@ inner class not found class Outer { } -new Outer:>Inner(); +new Outer\Inner(); ?> --EXPECTF-- -Fatal error: Inner class 'Outer:>Inner' not found in outer class Outer in %s on line %d +Fatal error: Uncaught Error: Class "Outer\Inner" not found in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/tests/classes/inner_classes/inheritance.phpt b/tests/classes/inner_classes/inheritance.phpt index 4addb7b02f61d..4f28583c0fc10 100644 --- a/tests/classes/inner_classes/inheritance.phpt +++ b/tests/classes/inner_classes/inheritance.phpt @@ -3,12 +3,14 @@ inheritance --FILE-- Other { - class Inner1 extends Outer:>Other {} - class Inner2 extends Outer:>Middle {} + class Middle extends Outer\Other { + class Inner1 extends Other {} + class Inner2 extends Inner1 {} } + abstract class Other {} } ?> --EXPECT-- diff --git a/tests/classes/inner_classes/interface_usage.phpt b/tests/classes/inner_classes/interface_usage.phpt index 2d3a071531d0a..e863e7b71bb88 100644 --- a/tests/classes/inner_classes/interface_usage.phpt +++ b/tests/classes/inner_classes/interface_usage.phpt @@ -7,15 +7,15 @@ interface Outer { class Inner {} } -var_dump(new Outer:>Inner()); +var_dump(new Outer\Inner()); class Foo implements Outer {} -var_dump(class_exists(Outer:>Inner::class)); -var_dump(class_exists(Foo:>Inner::class)); +var_dump(class_exists(Outer\Inner::class)); +var_dump(class_exists(Foo\Inner::class)); ?> --EXPECT-- -object(Outer:>Inner)#1 (0) { +object(Outer\Inner)#1 (0) { } bool(true) bool(false) diff --git a/tests/classes/inner_classes/readonly_001.phpt b/tests/classes/inner_classes/readonly_001.phpt index 189c9bcb23b7d..3fb85996605a3 100644 --- a/tests/classes/inner_classes/readonly_001.phpt +++ b/tests/classes/inner_classes/readonly_001.phpt @@ -7,17 +7,17 @@ class Outer { public readonly class Inner { public function __construct(public int $t) {} } } -var_dump($foo = new Outer:>Inner(1)); +var_dump($foo = new Outer\Inner(1)); $foo->t = 42; var_dump($foo); ?> --EXPECTF-- -object(Outer:>Inner)#1 (1) { +object(Outer\Inner)#1 (1) { ["t"]=> int(1) } -Fatal error: Uncaught Error: Cannot modify readonly property Outer:>Inner::$t in %s:%d +Fatal error: Uncaught Error: Cannot modify readonly property Outer\Inner::$t in %s:%d Stack trace: #0 {main} thrown in %s on line %d diff --git a/tests/classes/inner_classes/reflection_001.phpt b/tests/classes/inner_classes/reflection_001.phpt index 0f1f53bae838e..a284c82ebb498 100644 --- a/tests/classes/inner_classes/reflection_001.phpt +++ b/tests/classes/inner_classes/reflection_001.phpt @@ -12,7 +12,7 @@ class Outer { } $outer = new \ReflectionClass(Outer::class); -$ref = new \ReflectionClass('n\s\Outer:>Middle:>Inner'); +$ref = new \ReflectionClass('n\s\Outer\Middle\Inner'); var_dump($ref->getName()); var_dump($ref->getShortName()); var_dump($ref->isInnerClass()); @@ -22,8 +22,8 @@ var_dump($ref->isProtected()); var_dump($ref->isPublic()); ?> --EXPECT-- -string(24) "n\s\Outer:>Middle:>Inner" -string(20) "Outer:>Middle:>Inner" +string(24) "n\s\Outer\Middle\Inner" +string(20) "Outer\Middle\Inner" bool(true) bool(false) bool(false) diff --git a/tests/classes/inner_classes/return_types_001.phpt b/tests/classes/inner_classes/return_types_001.phpt index d7190df3644d0..4f2e5806def02 100644 --- a/tests/classes/inner_classes/return_types_001.phpt +++ b/tests/classes/inner_classes/return_types_001.phpt @@ -5,14 +5,14 @@ test return types class Outer { class Inner { - public static function test(): Outer:>Inner { - return new Outer:>Inner(); + public static function test(): Outer\Inner { + return new Outer\Inner(); } } } -var_dump(Outer:>Inner::test()); +var_dump(Outer\Inner::test()); ?> --EXPECT-- -object(Outer:>Inner)#1 (0) { +object(Outer\Inner)#1 (0) { } diff --git a/tests/classes/inner_classes/return_types_002.phpt b/tests/classes/inner_classes/return_types_002.phpt index b2929a6fdd148..160cf8f0205fd 100644 --- a/tests/classes/inner_classes/return_types_002.phpt +++ b/tests/classes/inner_classes/return_types_002.phpt @@ -6,8 +6,8 @@ private inner class class Outer { private class Inner {} - private function getInner(): self:>Inner { - return new self:>Inner(); + private function getInner(): Inner { + return new Inner(); } public function getInner2(): mixed { @@ -16,9 +16,9 @@ class Outer { } class Foo extends Outer { - public function getInner(): parent:>Inner { + public function getInner(): Outer\Inner { var_dump(parent::getInner2()); - return new parent:>Inner(); + return new Outer\Inner(); } } @@ -26,7 +26,11 @@ $outer = new Foo(); var_dump($outer->getInner()); ?> --EXPECTF-- -object(Outer:>Inner)#2 (0) { +object(Outer\Inner)#2 (0) { } -Fatal error: Cannot access private inner class 'Outer:>Inner' in %s on line %d +Fatal error: Uncaught Error: Cannot instantiate private class Outer\Inner from Foo in %s:%d +Stack trace: +#0 %s(%d): Foo->getInner() +#1 {main} + thrown in %s on line %d diff --git a/tests/classes/inner_classes/return_types_003.phpt b/tests/classes/inner_classes/return_types_003.phpt index 4326566956ca2..7b4b392167e0a 100644 --- a/tests/classes/inner_classes/return_types_003.phpt +++ b/tests/classes/inner_classes/return_types_003.phpt @@ -6,27 +6,27 @@ protected inner class class Outer { protected class Inner {} - protected function getInner(): self:>Inner { - return new self:>Inner(); + protected function getInner(): Inner { + return new Inner(); } } class Foo extends Outer { - public function getInner(): parent:>Inner { + public function getInner(): Outer\Inner { var_dump(parent::getInner()); - return new parent:>Inner(); + return new Outer\Inner(); } } $outer = new Foo(); var_dump($outer->getInner()); -var_dump(new Outer:>Inner()); +var_dump(new Outer\Inner()); ?> --EXPECTF-- -object(Outer:>Inner)#2 (0) { +object(Outer\Inner)#2 (0) { } -Fatal error: Uncaught TypeError: Public method getInner cannot return protected class Outer:>Inner in %s:%d +Fatal error: Uncaught TypeError: Public method getInner cannot return protected class Outer\Inner in %s:%d Stack trace: #0 %s(%d): Foo->getInner() #1 {main} diff --git a/tests/classes/inner_classes/return_types_004.phpt b/tests/classes/inner_classes/return_types_004.phpt index 0fbeacd246297..a5c8635031aa6 100644 --- a/tests/classes/inner_classes/return_types_004.phpt +++ b/tests/classes/inner_classes/return_types_004.phpt @@ -6,20 +6,20 @@ private return types class Outer { private class Inner {} - public static function getInner(): self:>Inner { - return new self:>Inner(); + public static function getInner(): Inner { + return new Inner(); } } $r = Outer::getInner(); -function test($r): Outer:>Inner { +function test($r): Outer\Inner { return $r; } var_dump($r); test($r); ?> --EXPECTF-- -Fatal error: Uncaught TypeError: Public method getInner cannot return private class Outer:>Inner in %s:%d +Fatal error: Uncaught TypeError: Public method getInner cannot return private class Outer\Inner in %s:%d Stack trace: #0 %s(%d): Outer::getInner() #1 {main} diff --git a/tests/classes/inner_classes/return_types_005.phpt b/tests/classes/inner_classes/return_types_005.phpt index 5c2ed4ae7de86..dbb4f15ddcc24 100644 --- a/tests/classes/inner_classes/return_types_005.phpt +++ b/tests/classes/inner_classes/return_types_005.phpt @@ -6,20 +6,20 @@ protected return types class Outer { protected class Inner {} - public static function getInner(): self:>Inner { - return new self:>Inner(); + public static function getInner(): Inner { + return new Inner(); } } $r = Outer::getInner(); -function test($r): Outer:>Inner { +function test($r): Outer\Inner { return $r; } var_dump($r); test($r); ?> --EXPECTF-- -Fatal error: Uncaught TypeError: Public method getInner cannot return protected class Outer:>Inner in %s:%d +Fatal error: Uncaught TypeError: Public method getInner cannot return protected class Outer\Inner in %s:%d Stack trace: #0 %s(%d): Outer::getInner() #1 {main} diff --git a/tests/classes/inner_classes/return_types_006.phpt b/tests/classes/inner_classes/return_types_006.phpt index cff19b727ad54..d530496a28b35 100644 --- a/tests/classes/inner_classes/return_types_006.phpt +++ b/tests/classes/inner_classes/return_types_006.phpt @@ -6,16 +6,16 @@ returning private inner from inner method class Outer { private class PrivateInner { public function test() { - return new Outer:>PrivateInner(); + return new PrivateInner(); } } - public function test(): mixed { return new self:>PrivateInner()->test(); } + public function test(): mixed { return new PrivateInner()->test(); } } $foo = new Outer()->test(); var_dump($foo); ?> --EXPECT-- -object(Outer:>PrivateInner)#3 (0) { +object(Outer\PrivateInner)#3 (0) { } diff --git a/tests/classes/inner_classes/simple_declaration_001.phpt b/tests/classes/inner_classes/simple_declaration_001.phpt index 8b53dd3b089b2..93e9b16f4b241 100644 --- a/tests/classes/inner_classes/simple_declaration_001.phpt +++ b/tests/classes/inner_classes/simple_declaration_001.phpt @@ -9,10 +9,10 @@ class Outer { } } -var_dump(class_exists('Outer:>Middle')); -var_dump(class_exists('Outer:>Middle:>Inner')); -var_dump(class_exists(Outer:>Middle::class)); -var_dump(class_exists(Outer:>Middle:>Inner::class)); +var_dump(class_exists('Outer\Middle')); +var_dump(class_exists('Outer\Middle\Inner')); +var_dump(class_exists(Outer\Middle::class)); +var_dump(class_exists(Outer\Middle\Inner::class)); ?> --EXPECT-- bool(true) diff --git a/tests/classes/inner_classes/simple_declaration_003.phpt b/tests/classes/inner_classes/simple_declaration_003.phpt index 13c84de709caa..1d8c59fd64ef2 100644 --- a/tests/classes/inner_classes/simple_declaration_003.phpt +++ b/tests/classes/inner_classes/simple_declaration_003.phpt @@ -14,7 +14,7 @@ class Outer { } } } -new Outer:>Middle:>Inner()->test(); +new Outer\Middle\Inner()->test(); ?> --EXPECT-- -Foo\Outer:>Middle:>Inner +Foo\Outer\Middle\Inner diff --git a/tests/classes/inner_classes/simple_declaration_004.phpt b/tests/classes/inner_classes/simple_declaration_004.phpt index 898045a3ee606..598e947468c9d 100644 --- a/tests/classes/inner_classes/simple_declaration_004.phpt +++ b/tests/classes/inner_classes/simple_declaration_004.phpt @@ -6,21 +6,21 @@ scope resolution access class Outer { public class Middle { } - public static function testSelf(): self:>Middle { - return new self:>Middle(); + public static function testSelf(): Middle { + return new Middle(); } } class Outer2 extends Outer { - public class Middle extends parent:>Middle { + public class Middle extends Outer\Middle { } - public static function testParent(): parent:>Middle { - return new parent:>Middle(); + public static function testParent(): Outer\Middle { + return new Outer\Middle(); } - public static function testSelf(): self:>Middle { - return new self:>Middle(); + public static function testSelf(): Middle { + return new Middle(); } } @@ -31,11 +31,11 @@ var_dump(Outer2::testSelf()); ?> --EXPECT-- -object(Outer:>Middle)#1 (0) { +object(Outer\Middle)#1 (0) { } -object(Outer:>Middle)#1 (0) { +object(Outer\Middle)#1 (0) { } -object(Outer2:>Middle)#1 (0) { +object(Outer\Middle)#1 (0) { } -object(Outer2:>Middle)#1 (0) { +object(Outer\Middle)#1 (0) { } diff --git a/tests/classes/inner_classes/simple_declaration_005.phpt b/tests/classes/inner_classes/simple_declaration_005.phpt new file mode 100644 index 0000000000000..b9552de94ec85 --- /dev/null +++ b/tests/classes/inner_classes/simple_declaration_005.phpt @@ -0,0 +1,42 @@ +--TEST-- +failed inheritance +--FILE-- + +--EXPECT-- +THIS IS WRONG +object(Outer\Middle)#1 (0) { +} +object(Outer\Middle)#1 (0) { +} +object(Outer\Middle)#1 (0) { +} +object(Outer\Middle)#1 (0) { +} diff --git a/tests/classes/inner_classes/static_resolution.phpt b/tests/classes/inner_classes/static_resolution.phpt deleted file mode 100644 index e67ed0cf65e6a..0000000000000 --- a/tests/classes/inner_classes/static_resolution.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -static resolution ---FILE-- -Inner(); - } -} -var_dump(new Outer()->test()); -?> ---EXPECTF-- -Fatal error: Cannot use the static modifier on an inner class in %s on line %d diff --git a/tests/classes/inner_classes/static_variables.phpt b/tests/classes/inner_classes/static_variables.phpt index e656a9648a2ca..debe1a5198e2c 100644 --- a/tests/classes/inner_classes/static_variables.phpt +++ b/tests/classes/inner_classes/static_variables.phpt @@ -14,17 +14,17 @@ class Outer { } } -var_dump(Outer:>Middle::class); -var_dump(Outer:>Middle::FOO); -var_dump(Outer:>Middle::$bar); -var_dump(Outer:>Middle:>Inner::class); -var_dump(Outer:>Middle:>Inner::FOO); -var_dump(Outer:>Middle:>Inner::$bar); +var_dump(Outer\Middle::class); +var_dump(Outer\Middle::FOO); +var_dump(Outer\Middle::$bar); +var_dump(Outer\Middle\Inner::class); +var_dump(Outer\Middle\Inner::FOO); +var_dump(Outer\Middle\Inner::$bar); ?> --EXPECT-- -string(13) "Outer:>Middle" +string(12) "Outer\Middle" string(3) "foo" int(42) -string(20) "Outer:>Middle:>Inner" +string(18) "Outer\Middle\Inner" string(3) "foo" int(42) diff --git a/tests/classes/inner_classes/trait_usage.phpt b/tests/classes/inner_classes/trait_usage.phpt index 1511b8a642214..6e618e1a09387 100644 --- a/tests/classes/inner_classes/trait_usage.phpt +++ b/tests/classes/inner_classes/trait_usage.phpt @@ -7,18 +7,18 @@ trait Outer { class Inner {} } -var_dump(new Outer:>Inner()); +var_dump(new Outer\Inner()); class Foo { use Outer; } -var_dump(class_exists(Outer:>Inner::class)); -var_dump(class_exists(Foo:>Inner::class)); +var_dump(class_exists(Outer\Inner::class)); +var_dump(class_exists(Foo\Inner::class)); ?> --EXPECT-- -object(Outer:>Inner)#1 (0) { +object(Outer\Inner)#1 (0) { } bool(true) bool(false) diff --git a/tests/classes/inner_classes/visibility_001.phpt b/tests/classes/inner_classes/visibility_001.phpt index 0473686689403..a1ac42e6e9736 100644 --- a/tests/classes/inner_classes/visibility_001.phpt +++ b/tests/classes/inner_classes/visibility_001.phpt @@ -5,10 +5,10 @@ outer class visibility class Outer { private class Inner {} - public Outer:>Inner $illegal; + public Inner $illegal; public function test(): void { - $this->illegal = new Outer:>Inner(); + $this->illegal = new Inner(); } } @@ -18,7 +18,7 @@ $x->test(); var_dump($x); ?> --EXPECTF-- -Fatal error: Uncaught TypeError: Cannot assign private Outer:>Inner to higher visibile property Outer::illegal in %s:%d +Fatal error: Uncaught TypeError: Cannot assign private Outer\Inner to higher visibile property Outer::illegal in %s:%d Stack trace: #0 %s(%d): Outer->test() #1 {main} diff --git a/tests/classes/inner_classes/visibility_002.phpt b/tests/classes/inner_classes/visibility_002.phpt index 8e99b87d15a15..7444229361281 100644 --- a/tests/classes/inner_classes/visibility_002.phpt +++ b/tests/classes/inner_classes/visibility_002.phpt @@ -9,10 +9,10 @@ class Outer { $i->illegal = $this; } } - private Outer:>Inner $illegal; + private Inner $illegal; public function test(): void { - new Outer:>Inner()->test($this); + new Inner()->test($this); } } @@ -25,6 +25,6 @@ var_dump($x); --EXPECT-- object(Outer)#1 (1) { ["illegal":"Outer":private]=> - object(Outer:>Inner)#2 (0) { + object(Outer\Inner)#2 (0) { } } diff --git a/tests/classes/inner_classes/visibility_003.phpt b/tests/classes/inner_classes/visibility_003.phpt index 66f42b2707838..07cbf29767ca0 100644 --- a/tests/classes/inner_classes/visibility_003.phpt +++ b/tests/classes/inner_classes/visibility_003.phpt @@ -9,10 +9,10 @@ class Outer { $i->illegal = $this; } } - private Outer:>Inner $illegal; + private Inner $illegal; public function test(): void { - new Outer:>Inner()->test($this); + new Inner()->test($this); } } @@ -25,6 +25,6 @@ var_dump($x); --EXPECT-- object(Outer)#1 (1) { ["illegal":"Outer":private]=> - object(Outer:>Inner)#2 (0) { + object(Outer\Inner)#2 (0) { } } diff --git a/tests/classes/inner_classes/visibility_004.phpt b/tests/classes/inner_classes/visibility_004.phpt index 38390f65c830e..c655bbe2c8b29 100644 --- a/tests/classes/inner_classes/visibility_004.phpt +++ b/tests/classes/inner_classes/visibility_004.phpt @@ -5,10 +5,10 @@ outer class visibility class Outer { protected class Inner {} - public Outer:>Inner $illegal; + public Inner $illegal; public function test(): void { - $this->illegal = new Outer:>Inner(); + $this->illegal = new Inner(); } } @@ -18,7 +18,7 @@ $x->test(); var_dump($x); ?> --EXPECTF-- -Fatal error: Uncaught TypeError: Cannot assign protected Outer:>Inner to higher visibile property Outer::illegal in %s:%d +Fatal error: Uncaught TypeError: Cannot assign protected Outer\Inner to higher visibile property Outer::illegal in %s:%d Stack trace: #0 %s(%d): Outer->test() #1 {main} diff --git a/tests/classes/inner_classes/visibility_005.phpt b/tests/classes/inner_classes/visibility_005.phpt index 32737d6cbc5ee..8624c36245220 100644 --- a/tests/classes/inner_classes/visibility_005.phpt +++ b/tests/classes/inner_classes/visibility_005.phpt @@ -13,15 +13,15 @@ class Outer { } class Inner { public function test() { - Outer:>Middle::test(); + Middle::test(); $t = new Outer(); $t->test(); } } } } -new Outer:>Middle:>Inner()->test(); +new Outer\Middle\Inner()->test(); ?> --EXPECT-- -Outer:>Middle::test +Outer\Middle::test Outer::test diff --git a/tests/classes/inner_classes/visibility_006.phpt b/tests/classes/inner_classes/visibility_006.phpt index b5f1cc13a8a38..de15166bb551b 100644 --- a/tests/classes/inner_classes/visibility_006.phpt +++ b/tests/classes/inner_classes/visibility_006.phpt @@ -18,11 +18,11 @@ class Outer { } } } -new Outer:>Middle:>Inner()->testit(); +new Outer\Middle\Inner()->testit(); ?> --EXPECTF-- -Fatal error: Uncaught Error: Call to undefined method Outer:>Middle:>Inner::test() in %s:%d +Fatal error: Uncaught Error: Call to undefined method Outer\Middle\Inner::test() in %s:%d Stack trace: -#0 %s(%d): Outer:>Middle:>Inner->testit() +#0 %s(%d): Outer\Middle\Inner->testit() #1 {main} thrown in %s on line %d diff --git a/tests/classes/inner_classes/visibility_007.phpt b/tests/classes/inner_classes/visibility_007.phpt index 5ed1ebcae5bca..3da65bface64a 100644 --- a/tests/classes/inner_classes/visibility_007.phpt +++ b/tests/classes/inner_classes/visibility_007.phpt @@ -13,15 +13,15 @@ class Outer { } class Inner { public function test() { - Outer:>Middle::test(); + Middle::test(); $t = new Outer(); $t->test(); } } } } -new Outer:>Middle:>Inner()->test(); +new Outer\Middle\Inner()->test(); ?> --EXPECT-- -Outer:>Middle::test +Outer\Middle::test Outer::test diff --git a/tests/classes/inner_classes/visibility_008.phpt b/tests/classes/inner_classes/visibility_008.phpt index 6a5d8dadf94c5..cbb8657fc632e 100644 --- a/tests/classes/inner_classes/visibility_008.phpt +++ b/tests/classes/inner_classes/visibility_008.phpt @@ -17,14 +17,14 @@ class Outer { class Other extends Outer { class Inner { public function test() { - Outer:>Middle::test(); + Outer\Middle::test(); $t = new Outer(); $t->test(); } } } -new Other:>Inner()->test(); +new Other\Inner()->test(); ?> --EXPECT-- -Outer:>Middle::test +Outer\Middle::test Outer::test diff --git a/tests/classes/inner_classes/visibility_009.phpt b/tests/classes/inner_classes/visibility_009.phpt index 4bf9ce96dd250..3c267d109984b 100644 --- a/tests/classes/inner_classes/visibility_009.phpt +++ b/tests/classes/inner_classes/visibility_009.phpt @@ -12,18 +12,18 @@ class Outer { class Inner { public static function test() { var_dump(Outer::$j = 5); - var_dump(Outer:>Middle::$j = 42); + var_dump(Middle::$j = 42); $foo = new Outer(); $foo->i = 42; var_dump($foo); - $foo = new Outer:>Middle(); + $foo = new Middle(); $foo->i = 42; var_dump($foo); } } } } -Outer:>Middle:>Inner::test(); +Outer\Middle\Inner::test(); ?> --EXPECT-- int(5) @@ -32,7 +32,7 @@ object(Outer)#1 (1) { ["i":"Outer":private]=> int(42) } -object(Outer:>Middle)#2 (1) { - ["i":"Outer:>Middle":private]=> +object(Outer\Middle)#2 (1) { + ["i":"Outer\Middle":private]=> int(42) } diff --git a/tests/classes/inner_classes/visibility_010.phpt b/tests/classes/inner_classes/visibility_010.phpt index d70478ba09a57..b6e94ddf7d359 100644 --- a/tests/classes/inner_classes/visibility_010.phpt +++ b/tests/classes/inner_classes/visibility_010.phpt @@ -7,7 +7,7 @@ class User { public private(set) string $name; public private(set) string $email; - private function __construct(self:>Builder $builder) { + private function __construct(Builder $builder) { $this->name = $builder->name; $this->email = $builder->email; } @@ -29,7 +29,7 @@ class User { } } -$user = new User:>Builder()->withName('Rob')->withEmail('rob@example.com')->build(); +$user = new User\Builder()->withName('Rob')->withEmail('rob@example.com')->build(); var_dump($user); ?> --EXPECT-- From 4f441cb75d226244ee809ae177b32ce00213afa2 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 09:58:09 +0100 Subject: [PATCH 42/65] do not elide return checks for inner classes --- Zend/Optimizer/dfa_pass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/Optimizer/dfa_pass.c b/Zend/Optimizer/dfa_pass.c index 2c3aaae065997..fe1c25bda2cc8 100644 --- a/Zend/Optimizer/dfa_pass.c +++ b/Zend/Optimizer/dfa_pass.c @@ -282,7 +282,7 @@ static inline bool can_elide_list_type( zend_string *lcname = zend_string_tolower(ZEND_TYPE_NAME(*single_type)); zend_class_entry *ce = zend_optimizer_get_class_entry(script, op_array, lcname); zend_string_release(lcname); - bool result = ce && safe_instanceof(use_info->ce, ce); + bool result = ce && !ce->required_scope && safe_instanceof(use_info->ce, ce); if (result == !is_intersection) { return result; } From d9ae53b13430a45c8d8e214bbe87d69c3dcd22a0 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 09:59:08 +0100 Subject: [PATCH 43/65] do visibility check during instantiation --- Zend/zend_API.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 7023bf1a36b4b..3f81d83d8a61b 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1816,6 +1816,30 @@ static zend_always_inline zend_result _object_and_properties_init(zval *arg, zen return FAILURE; } + if (class_type->required_scope) { + const zend_class_entry *scope = zend_get_executed_scope(); + if (UNEXPECTED(scope == NULL)) { + zend_throw_error(NULL, "Cannot instantiate class %s from the global scope", ZSTR_VAL(class_type->name)); + ZVAL_NULL(arg); + Z_OBJ_P(arg) = NULL; + return FAILURE; + } + + if (class_type->required_scope_absolute) { + if (scope != class_type->required_scope && scope->lexical_scope != class_type->required_scope) { + zend_throw_error(NULL, "Cannot instantiate private class %s from %s", ZSTR_VAL(class_type->name), ZSTR_VAL(scope->name)); + ZVAL_NULL(arg); + Z_OBJ_P(arg) = NULL; + return FAILURE; + } + } else if (!instanceof_function(scope, class_type->required_scope) && !instanceof_function(scope->lexical_scope, class_type->required_scope)) { + zend_throw_error(NULL, "Cannot instantiate protected class %s from %s", ZSTR_VAL(class_type->name), ZSTR_VAL(scope->name)); + ZVAL_NULL(arg); + Z_OBJ_P(arg) = NULL; + return FAILURE; + } + } + if (UNEXPECTED(!(class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) { if (UNEXPECTED(zend_update_class_constants(class_type) != SUCCESS)) { ZVAL_NULL(arg); From 864c4c6519efd9af30e9921ded91be7e7eec28de Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 09:59:30 +0100 Subject: [PATCH 44/65] replace wrong token --- Zend/zend_compile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c68d86d2e5eda..0ed79c9a09218 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1818,7 +1818,7 @@ static zend_string *zend_resolve_nested_class_name(zend_ast *ast) /* {{{ */ full_name = zend_string_concat3( ZSTR_VAL(outer_name), ZSTR_LEN(outer_name), - ":>", 2, + "\\", 1, ZSTR_VAL(inner_name), ZSTR_LEN(inner_name) ); From c342b5d633c66554dfef2399afd14b7d6bfced24 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 10:00:33 +0100 Subject: [PATCH 45/65] remove inner class AST --- Zend/zend_compile.c | 35 --------------- Zend/zend_vm_def.h | 103 -------------------------------------------- 2 files changed, 138 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 0ed79c9a09218..e310573f23801 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2921,42 +2921,10 @@ static inline void zend_set_class_name_op1(zend_op *opline, znode *class_node) / } /* }}} */ -static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t fetch_flags); - -static void zend_compile_inner_class_ref(znode *result, zend_ast *ast, uint32_t fetch_flags) /* {{{ */ -{ - zend_ast *outer_class = ast->child[0]; - zend_ast *inner_class = ast->child[1]; - - znode outer_node, inner_node; - - // handle nesting - if (outer_class->kind == ZEND_AST_INNER_CLASS) { - zend_compile_inner_class_ref(&outer_node, outer_class, fetch_flags); - } else { - zend_compile_class_ref(&outer_node, outer_class, fetch_flags | ZEND_FETCH_CLASS_OUTER); - } - - if (inner_class->kind == ZEND_AST_ZVAL && Z_TYPE_P(zend_ast_get_zval(inner_class)) == IS_STRING) { - ZVAL_STR(&inner_node.u.constant, zend_string_dup(Z_STR_P(zend_ast_get_zval(inner_class)), 0)); - inner_node.op_type = IS_CONST; - } else { - zend_compile_expr(&inner_node, inner_class); - } - - zend_emit_op(result, ZEND_FETCH_INNER_CLASS, &outer_node, &inner_node); -} -/* }}} */ - static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t fetch_flags) /* {{{ */ { uint32_t fetch_type; - if (name_ast->kind == ZEND_AST_INNER_CLASS) { - zend_compile_inner_class_ref(result, name_ast, fetch_flags); - return; - } - if (name_ast->kind != ZEND_AST_ZVAL) { znode name_node; @@ -11912,9 +11880,6 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ case ZEND_AST_MATCH: zend_compile_match(result, ast); return; - case ZEND_AST_INNER_CLASS: - zend_compile_inner_class_ref(result, ast, ZEND_FETCH_CLASS_EXCEPTION); - return; default: ZEND_ASSERT(0 /* not supported */); } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 816f7c1ccdd4a..be154ddf8a8e0 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1798,108 +1798,6 @@ ZEND_VM_C_LABEL(fetch_this): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(210, ZEND_FETCH_INNER_CLASS, CONST|TMPVAR|UNUSED, CONST, CACHE_SLOT) -{ - USE_OPLINE - SAVE_OPLINE(); - - zend_string *inner_class_name, *full_class_name; - zend_class_entry *outer_ce = NULL, *inner_ce = NULL, *scope = NULL; - - scope = EX(func)->op_array.scope; - - if (OP1_TYPE == IS_CONST) { - zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); - outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv)); - if (!outer_ce) { - zend_error(E_ERROR, "Outer class '%s' not found for inner class %s:>%s", Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); - HANDLE_EXCEPTION(); - } - } else if (OP1_TYPE == IS_UNUSED) { - uint32_t fetch_type; - zend_class_entry *called_scope; - - fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK; - if (UNEXPECTED(scope == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", - fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : - fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - if (fetch_type == ZEND_FETCH_CLASS_SELF) { - outer_ce = scope; - } else if (fetch_type == ZEND_FETCH_CLASS_PARENT) { - if (UNEXPECTED(scope->parent == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, - "Cannot use \"parent\" when current class scope has no parent"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - outer_ce = scope->parent; - } else if (fetch_type == ZEND_FETCH_CLASS_STATIC) { - if (Z_TYPE(EX(This)) == IS_OBJECT) { - called_scope = Z_OBJCE(EX(This)); - } else { - called_scope = Z_CE(EX(This)); - } - outer_ce = called_scope; - } else { - zend_throw_error(NULL, "Unknown scope resolution"); - HANDLE_EXCEPTION(); - } - } else { - outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - - if (UNEXPECTED(ZSTR_LEN(outer_ce->name) + ZSTR_LEN(inner_class_name) + 2 > ZSTR_MAX_LEN)) { - zend_error(E_ERROR, "Class name is too long"); - HANDLE_EXCEPTION(); - } - - full_class_name = zend_string_concat3( - ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name), - ":>", 2, - ZSTR_VAL(inner_class_name), ZSTR_LEN(inner_class_name) - ); - - inner_ce = zend_lookup_class(full_class_name); - if (!inner_ce) { - zend_error(E_ERROR, "Inner class '%s' not found in outer class %s", ZSTR_VAL(full_class_name), ZSTR_VAL(outer_ce->name)); - HANDLE_EXCEPTION(); - } - - if (inner_ce->required_scope) { - if (inner_ce->required_scope_absolute) { - // for private classes, we check if the scope we are currently in has access - if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) { - // we are in the correct scope - } else { - zend_error(E_ERROR, "Cannot access private inner class '%s'", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); - } - } else { - // for protected classes, we check if the scope is an instance of the required scope - if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) { - // we are in the correct scope - } else { - zend_error(E_ERROR, "Cannot access protected inner class '%s'", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); - } - } - } - - Z_CE_P(EX_VAR(opline->result.var)) = inner_ce; - - zend_string_release(full_class_name); - - ZEND_VM_NEXT_OPCODE(); -} - ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R); @@ -8293,7 +8191,6 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) case ZEND_FETCH_CLASS: case ZEND_DECLARE_ANON_CLASS: - case ZEND_FETCH_INNER_CLASS: break; /* return value is zend_class_entry pointer */ default: From 6c288748ef0e7749515e291e424a444ec8d071e1 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 10:01:20 +0100 Subject: [PATCH 46/65] defer compiling inner classes --- Zend/zend_compile.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index e310573f23801..2222a5f813855 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -9296,6 +9296,22 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) zend_verify_abstract_class(ce); } + if (inner_class_queue == NULL) { + CG(active_class_entry) = original_ce; + } else { + HashTable *queue = inner_class_queue; + inner_class_queue = NULL; + + ZEND_HASH_FOREACH_PTR(queue, ast) { + zend_compile_class_decl(NULL, ast, 0); + } ZEND_HASH_FOREACH_END(); + + CG(active_class_entry) = original_ce; + + zend_hash_destroy(queue); + FREE_HASHTABLE(queue); + } + if (toplevel) { ce->ce_flags |= ZEND_ACC_TOP_LEVEL; } @@ -9316,7 +9332,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) && !zend_compile_ignore_class(parent_ce, ce->info.user.filename)) { if (zend_try_early_bind(ce, parent_ce, lcname, NULL)) { zend_string_release(lcname); - goto compile_inner_classes; + return; } } } else if (EXPECTED(zend_hash_add_ptr(CG(class_table), lcname, ce) != NULL)) { @@ -9325,7 +9341,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) zend_inheritance_check_override(ce); ce->ce_flags |= ZEND_ACC_LINKED; zend_observer_class_linked_notify(ce, lcname); - goto compile_inner_classes; + return; } else { goto link_unbound; } @@ -9395,24 +9411,6 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) opline->result.opline_num = -1; } } - compile_inner_classes: - - if (inner_class_queue == NULL) { - CG(active_class_entry) = original_ce; - return; - } - - HashTable *queue = inner_class_queue; - inner_class_queue = NULL; - - ZEND_HASH_FOREACH_PTR(queue, ast) { - zend_compile_class_decl(NULL, ast, 0); - } ZEND_HASH_FOREACH_END(); - - CG(active_class_entry) = original_ce; - - zend_hash_destroy(queue); - FREE_HASHTABLE(queue); } /* }}} */ @@ -11703,6 +11701,10 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ zend_compile_use_trait(ast); break; case ZEND_AST_CLASS: + if (CG(active_class_entry)) { + zend_defer_class_decl(ast); + break; + } zend_compile_class_decl(NULL, ast, 0); break; case ZEND_AST_GROUP_USE: From a92ba6322fe18f650054fdd0ee7370342e10a2ab Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 10:02:05 +0100 Subject: [PATCH 47/65] allow looking up classes in scopes --- Zend/zend_execute.h | 1 + Zend/zend_execute_API.c | 77 ++++++++++++++++++++++++++++++----------- Zend/zend_inheritance.c | 18 +++++++--- Zend/zend_namespaces.c | 10 +++++- Zend/zend_namespaces.h | 3 +- 5 files changed, 81 insertions(+), 28 deletions(-) diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 3b8ed89ec4f38..932ded88ee53f 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -49,6 +49,7 @@ ZEND_API void execute_ex(zend_execute_data *execute_data); ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value); ZEND_API bool zend_is_valid_class_name(zend_string *name); ZEND_API zend_class_entry *zend_lookup_class(zend_string *name); +ZEND_API zend_class_entry *zend_lookup_class_in_scope(zend_string *name, const zend_class_entry *scope); ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *lcname, uint32_t flags); ZEND_API zend_class_entry *zend_get_called_scope(zend_execute_data *ex); ZEND_API zend_object *zend_get_this_object(zend_execute_data *ex); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 75046719cbb4a..3e4ec6bb04405 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -20,6 +20,7 @@ #include #include +#include #include "zend.h" #include "zend_compile.h" @@ -1167,13 +1168,14 @@ ZEND_API bool zend_is_valid_class_name(zend_string *name) { } static zend_string *get_namespace_from_scope(const zend_class_entry *scope) { + ZEND_ASSERT(scope != NULL); while (scope && scope->lexical_scope && scope->type != ZEND_NAMESPACE_CLASS) { scope = scope->lexical_scope; } - return scope->name; + return zend_string_copy(scope->name); } -static zend_string *get_scoped_name(const zend_string *ns, zend_string *name) { +static zend_string *get_scoped_name(zend_string *ns, zend_string *name) { // remove the matching prefix from name name = zend_string_tolower(name); if (ns && ZSTR_LEN(ns) && ZSTR_LEN(name) > ZSTR_LEN(ns) + 1 && @@ -1183,10 +1185,44 @@ static zend_string *get_scoped_name(const zend_string *ns, zend_string *name) { zend_string_release(name); return ret; } - zend_string_release(name); return name; } +zend_class_entry *zend_lookup_class_in_scope(zend_string *name, const zend_class_entry *scope) { + zend_class_entry *ce = NULL; + zend_string *ns_name = get_namespace_from_scope(scope); + zend_string *original_suffix = get_scoped_name(ns_name, name); + zend_string_release(ns_name); + + const zend_class_entry *current_scope = scope; + + // Traverse upwards in lexical scope, stop at namespace boundary + while (current_scope && current_scope->type != ZEND_NAMESPACE_CLASS) { + // build fully-qualified name: current_scope->name + "\\" + original_suffix + zend_string *try_name = zend_string_concat3( + ZSTR_VAL(current_scope->name), ZSTR_LEN(current_scope->name), + "\\", 1, + ZSTR_VAL(original_suffix), ZSTR_LEN(original_suffix) + ); + + zend_string *lc_try_name = zend_string_tolower(try_name); + zend_string_release(try_name); + + ce = zend_hash_find_ptr(EG(class_table), lc_try_name); + zend_string_release(lc_try_name); + + if (ce) { + zend_string_release(original_suffix); + return ce; + } + + current_scope = current_scope->lexical_scope; + } + + zend_string_release(original_suffix); + return NULL; +} + ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *key, uint32_t flags) /* {{{ */ { zend_class_entry *ce = NULL; @@ -1205,26 +1241,25 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * if (!zend_is_compiling()) { const zend_class_entry *scope = zend_get_executed_scope(); - if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) { - zend_string *ns_name = get_namespace_from_scope(scope); - zend_string *scoped_name = get_scoped_name(ns_name, name); - while (scope->type != ZEND_NAMESPACE_CLASS) { - zend_string *try_name = zend_string_concat3(ZSTR_VAL(scope->name), ZSTR_LEN(scope->name), "\\", 1, ZSTR_VAL(scoped_name), ZSTR_LEN(scoped_name)); - lc_name = zend_string_tolower(try_name); - ce = zend_hash_find_ptr(EG(class_table), lc_name); - if (ce) { - zend_string_release(lc_name); - zend_string_release(scoped_name); - zend_string_release(ns_name); - zend_string_release(try_name); - return ce; + if (scope) { + ce = zend_lookup_class_in_scope(name, scope); + if (ce) { + if (ce_cache) { + SET_CE_CACHE(ce_cache, ce); } - scope = scope->lexical_scope; - zend_string_release(lc_name); - zend_string_release(try_name); + return ce; + } + } + } else if (CG(active_class_entry)) { + const zend_class_entry *scope = CG(active_class_entry); + if (scope) { + ce = zend_lookup_class_in_scope(name, scope); + if (ce) { + if (ce_cache) { + SET_CE_CACHE(ce_cache, ce); + } + return ce; } - zend_string_release(ns_name); - zend_string_release(scoped_name); } } diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index bcccf978e2a01..84a5435596135 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -280,8 +280,12 @@ static zend_class_entry *lookup_class_ex( return ce; } - ce = zend_lookup_class_ex( - name, NULL, ZEND_FETCH_CLASS_ALLOW_UNLINKED | ZEND_FETCH_CLASS_NO_AUTOLOAD); + ce = zend_lookup_class_in_scope(name, scope); + + if (!ce) { + ce = zend_lookup_class_ex( + name, NULL, ZEND_FETCH_CLASS_ALLOW_UNLINKED | ZEND_FETCH_CLASS_NO_AUTOLOAD); + } if (!CG(in_compilation) || in_preload) { if (ce) { @@ -3531,9 +3535,13 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED)); if (ce->parent_name) { - parent = zend_fetch_class_by_name( - ce->parent_name, lc_parent_name, - ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED | ZEND_FETCH_CLASS_EXCEPTION); + parent = zend_lookup_class_in_scope(ce->parent_name, ce); + + if (!parent) { + parent = zend_fetch_class_by_name( + ce->parent_name, lc_parent_name, + ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED | ZEND_FETCH_CLASS_EXCEPTION); + } if (!parent) { check_unrecoverable_load_failure(ce); return NULL; diff --git a/Zend/zend_namespaces.c b/Zend/zend_namespaces.c index 38b3ab636a9b2..fe061d30866de 100644 --- a/Zend/zend_namespaces.c +++ b/Zend/zend_namespaces.c @@ -107,12 +107,20 @@ zend_class_entry *zend_resolve_namespace(zend_string *name) { return ns; } +zend_class_entry *zend_lookup_namespace(zend_string *name) { + zend_string *lc_name = zend_string_tolower(name); + zend_class_entry *ns = zend_hash_find_ptr(&namespaces, lc_name); + zend_string_release(lc_name); + + return ns; +} + void zend_destroy_namespaces(void) { if (global_namespace == NULL) { return; } - const zend_class_entry *ns = NULL; + zend_class_entry *ns = NULL; ZEND_HASH_FOREACH_PTR(&namespaces, ns) { zend_string_release(ns->name); } ZEND_HASH_FOREACH_END(); diff --git a/Zend/zend_namespaces.h b/Zend/zend_namespaces.h index 4879fd7039119..f4030a5090e2c 100644 --- a/Zend/zend_namespaces.h +++ b/Zend/zend_namespaces.h @@ -23,7 +23,8 @@ #include "zend.h" #include "zend_compile.h" -zend_class_entry *zend_resolve_namespace(zend_string *name); +ZEND_API zend_class_entry *zend_resolve_namespace(zend_string *name); void zend_destroy_namespaces(void); +ZEND_API zend_class_entry *zend_lookup_namespace(zend_string *name); #endif //ZEND_NAMESPACES_H From bbc0fed87226a89e8cbb2a59418aa15b3f25bd7d Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 10:02:15 +0100 Subject: [PATCH 48/65] fix isInnerClass --- ext/reflection/php_reflection.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index c297426c06d9a..eb600535a96bf 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4079,16 +4079,12 @@ static void add_class_vars(zend_class_entry *ce, bool statics, zval *return_valu ZEND_METHOD(ReflectionClass, isInnerClass) { reflection_object *intern; - zend_class_entry *ce; - - ZEND_PARSE_PARAMETERS_NONE(); - - GET_REFLECTION_OBJECT_PTR(ce); + zend_class_entry *ce; + ZEND_PARSE_PARAMETERS_NONE(); - // If the class is an inner class, it will have a T_INNER_REF in its name - // todo: make this better? + GET_REFLECTION_OBJECT_PTR(ce); - RETURN_BOOL(strstr(ZSTR_VAL(ce->name), ":>") != NULL); + RETURN_BOOL(ce->lexical_scope && ce->lexical_scope->type != ZEND_NAMESPACE_CLASS); } /* }}} */ From ce0db15b7d9a7ca834db93275173882957eca0c8 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 10:02:44 +0100 Subject: [PATCH 49/65] add build artifacts --- Zend/zend_vm_execute.h | 516 ++++------------------ Zend/zend_vm_handlers.h | 922 ++++++++++++++++++++-------------------- Zend/zend_vm_opcodes.c | 6 +- Zend/zend_vm_opcodes.h | 3 +- 4 files changed, 554 insertions(+), 893 deletions(-) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 86b9776665d4c..1f87aacdb444f 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3310,7 +3310,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER( case ZEND_FETCH_CLASS: case ZEND_DECLARE_ANON_CLASS: - case ZEND_FETCH_INNER_CLASS: break; /* return value is zend_class_entry pointer */ default: @@ -6611,108 +6610,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CON ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - SAVE_OPLINE(); - - zend_string *inner_class_name, *full_class_name; - zend_class_entry *outer_ce = NULL, *inner_ce = NULL, *scope = NULL; - - scope = EX(func)->op_array.scope; - - if (IS_CONST == IS_CONST) { - zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); - outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv)); - if (!outer_ce) { - zend_error(E_ERROR, "Outer class '%s' not found for inner class %s:>%s", Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); - HANDLE_EXCEPTION(); - } - } else if (IS_CONST == IS_UNUSED) { - uint32_t fetch_type; - zend_class_entry *called_scope; - - fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK; - if (UNEXPECTED(scope == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", - fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : - fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - if (fetch_type == ZEND_FETCH_CLASS_SELF) { - outer_ce = scope; - } else if (fetch_type == ZEND_FETCH_CLASS_PARENT) { - if (UNEXPECTED(scope->parent == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, - "Cannot use \"parent\" when current class scope has no parent"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - outer_ce = scope->parent; - } else if (fetch_type == ZEND_FETCH_CLASS_STATIC) { - if (Z_TYPE(EX(This)) == IS_OBJECT) { - called_scope = Z_OBJCE(EX(This)); - } else { - called_scope = Z_CE(EX(This)); - } - outer_ce = called_scope; - } else { - zend_throw_error(NULL, "Unknown scope resolution"); - HANDLE_EXCEPTION(); - } - } else { - outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - - if (UNEXPECTED(ZSTR_LEN(outer_ce->name) + ZSTR_LEN(inner_class_name) + 2 > ZSTR_MAX_LEN)) { - zend_error(E_ERROR, "Class name is too long"); - HANDLE_EXCEPTION(); - } - - full_class_name = zend_string_concat3( - ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name), - ":>", 2, - ZSTR_VAL(inner_class_name), ZSTR_LEN(inner_class_name) - ); - - inner_ce = zend_lookup_class(full_class_name); - if (!inner_ce) { - zend_error(E_ERROR, "Inner class '%s' not found in outer class %s", ZSTR_VAL(full_class_name), ZSTR_VAL(outer_ce->name)); - HANDLE_EXCEPTION(); - } - - if (inner_ce->required_scope) { - if (inner_ce->required_scope_absolute) { - // for private classes, we check if the scope we are currently in has access - if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) { - // we are in the correct scope - } else { - zend_error(E_ERROR, "Cannot access private inner class '%s'", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); - } - } else { - // for protected classes, we check if the scope is an instance of the required scope - if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) { - // we are in the correct scope - } else { - zend_error(E_ERROR, "Cannot access protected inner class '%s'", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); - } - } - } - - Z_CE_P(EX_VAR(opline->result.var)) = inner_ce; - - zend_string_release(full_class_name); - - ZEND_VM_NEXT_OPCODE(); -} - static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -16248,108 +16145,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HAN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - SAVE_OPLINE(); - - zend_string *inner_class_name, *full_class_name; - zend_class_entry *outer_ce = NULL, *inner_ce = NULL, *scope = NULL; - - scope = EX(func)->op_array.scope; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); - outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv)); - if (!outer_ce) { - zend_error(E_ERROR, "Outer class '%s' not found for inner class %s:>%s", Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); - HANDLE_EXCEPTION(); - } - } else if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - uint32_t fetch_type; - zend_class_entry *called_scope; - - fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK; - if (UNEXPECTED(scope == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", - fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : - fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - if (fetch_type == ZEND_FETCH_CLASS_SELF) { - outer_ce = scope; - } else if (fetch_type == ZEND_FETCH_CLASS_PARENT) { - if (UNEXPECTED(scope->parent == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, - "Cannot use \"parent\" when current class scope has no parent"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - outer_ce = scope->parent; - } else if (fetch_type == ZEND_FETCH_CLASS_STATIC) { - if (Z_TYPE(EX(This)) == IS_OBJECT) { - called_scope = Z_OBJCE(EX(This)); - } else { - called_scope = Z_CE(EX(This)); - } - outer_ce = called_scope; - } else { - zend_throw_error(NULL, "Unknown scope resolution"); - HANDLE_EXCEPTION(); - } - } else { - outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - - if (UNEXPECTED(ZSTR_LEN(outer_ce->name) + ZSTR_LEN(inner_class_name) + 2 > ZSTR_MAX_LEN)) { - zend_error(E_ERROR, "Class name is too long"); - HANDLE_EXCEPTION(); - } - - full_class_name = zend_string_concat3( - ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name), - ":>", 2, - ZSTR_VAL(inner_class_name), ZSTR_LEN(inner_class_name) - ); - - inner_ce = zend_lookup_class(full_class_name); - if (!inner_ce) { - zend_error(E_ERROR, "Inner class '%s' not found in outer class %s", ZSTR_VAL(full_class_name), ZSTR_VAL(outer_ce->name)); - HANDLE_EXCEPTION(); - } - - if (inner_ce->required_scope) { - if (inner_ce->required_scope_absolute) { - // for private classes, we check if the scope we are currently in has access - if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) { - // we are in the correct scope - } else { - zend_error(E_ERROR, "Cannot access private inner class '%s'", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); - } - } else { - // for protected classes, we check if the scope is an instance of the required scope - if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) { - // we are in the correct scope - } else { - zend_error(E_ERROR, "Cannot access protected inner class '%s'", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); - } - } - } - - Z_CE_P(EX_VAR(opline->result.var)) = inner_ce; - - zend_string_release(full_class_name); - - ZEND_VM_NEXT_OPCODE(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -34003,108 +33798,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - SAVE_OPLINE(); - - zend_string *inner_class_name, *full_class_name; - zend_class_entry *outer_ce = NULL, *inner_ce = NULL, *scope = NULL; - - scope = EX(func)->op_array.scope; - - if (IS_UNUSED == IS_CONST) { - zval *outer_class_zv = RT_CONSTANT(opline, opline->op1); - outer_ce = zend_lookup_class(Z_STR_P(outer_class_zv)); - if (!outer_ce) { - zend_error(E_ERROR, "Outer class '%s' not found for inner class %s:>%s", Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(outer_class_zv), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); - HANDLE_EXCEPTION(); - } - } else if (IS_UNUSED == IS_UNUSED) { - uint32_t fetch_type; - zend_class_entry *called_scope; - - fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK; - if (UNEXPECTED(scope == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", - fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : - fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - if (fetch_type == ZEND_FETCH_CLASS_SELF) { - outer_ce = scope; - } else if (fetch_type == ZEND_FETCH_CLASS_PARENT) { - if (UNEXPECTED(scope->parent == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, - "Cannot use \"parent\" when current class scope has no parent"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - outer_ce = scope->parent; - } else if (fetch_type == ZEND_FETCH_CLASS_STATIC) { - if (Z_TYPE(EX(This)) == IS_OBJECT) { - called_scope = Z_OBJCE(EX(This)); - } else { - called_scope = Z_CE(EX(This)); - } - outer_ce = called_scope; - } else { - zend_throw_error(NULL, "Unknown scope resolution"); - HANDLE_EXCEPTION(); - } - } else { - outer_ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - inner_class_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - - if (UNEXPECTED(ZSTR_LEN(outer_ce->name) + ZSTR_LEN(inner_class_name) + 2 > ZSTR_MAX_LEN)) { - zend_error(E_ERROR, "Class name is too long"); - HANDLE_EXCEPTION(); - } - - full_class_name = zend_string_concat3( - ZSTR_VAL(outer_ce->name), ZSTR_LEN(outer_ce->name), - ":>", 2, - ZSTR_VAL(inner_class_name), ZSTR_LEN(inner_class_name) - ); - - inner_ce = zend_lookup_class(full_class_name); - if (!inner_ce) { - zend_error(E_ERROR, "Inner class '%s' not found in outer class %s", ZSTR_VAL(full_class_name), ZSTR_VAL(outer_ce->name)); - HANDLE_EXCEPTION(); - } - - if (inner_ce->required_scope) { - if (inner_ce->required_scope_absolute) { - // for private classes, we check if the scope we are currently in has access - if (scope != NULL && (inner_ce->required_scope == scope || scope->lexical_scope == inner_ce->required_scope)) { - // we are in the correct scope - } else { - zend_error(E_ERROR, "Cannot access private inner class '%s'", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); - } - } else { - // for protected classes, we check if the scope is an instance of the required scope - if (scope != NULL && (instanceof_function(scope, inner_ce->required_scope) || instanceof_function(scope->lexical_scope, inner_ce->required_scope))) { - // we are in the correct scope - } else { - zend_error(E_ERROR, "Cannot access protected inner class '%s'", ZSTR_VAL(full_class_name)); - HANDLE_EXCEPTION(); - } - } - } - - Z_CE_P(EX_VAR(opline->result.var)) = inner_ce; - - zend_string_release(full_class_name); - - ZEND_VM_NEXT_OPCODE(); -} - static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -58040,11 +57733,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER_LABEL, (void*)&&ZEND_JMP_FRAMELESS_SPEC_CONST_LABEL, (void*)&&ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_LABEL, - (void*)&&ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_FCALL_OFFSET_SPEC_CONST_LABEL, (void*)&&ZEND_RECV_NOTYPE_SPEC_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -59916,11 +59604,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_BOOL_XOR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_CONST_CONST) HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST): - VM_TRACE(ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST) - ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST) - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CONST_CONST): VM_TRACE(ZEND_FETCH_DIM_R_SPEC_CONST_CONST) ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -61191,11 +60874,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_TMPVAR_CONST) HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST) - ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST): VM_TRACE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -62784,11 +62462,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST): - VM_TRACE(ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST) - ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST) - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST): VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST) ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -67247,11 +66920,6 @@ void zend_vm_init(void) ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER_HANDLER, ZEND_JMP_FRAMELESS_SPEC_CONST_HANDLER, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_HANDLER, - ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST_HANDLER, - ZEND_NULL_HANDLER, ZEND_INIT_FCALL_OFFSET_SPEC_CONST_HANDLER, ZEND_RECV_NOTYPE_SPEC_HANDLER, ZEND_NULL_HANDLER, @@ -68209,7 +67877,7 @@ void zend_vm_init(void) 1255, 1256 | SPEC_RULE_OP1, 1261 | SPEC_RULE_OP1, - 3491, + 3486, 1266 | SPEC_RULE_OP1, 1271 | SPEC_RULE_OP1, 1276 | SPEC_RULE_OP2, @@ -68243,7 +67911,7 @@ void zend_vm_init(void) 1559 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1584 | SPEC_RULE_OP1, 1589, - 3491, + 3486, 1590 | SPEC_RULE_OP1, 1595 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1620 | SPEC_RULE_OP1 | SPEC_RULE_OP2, @@ -68374,52 +68042,52 @@ void zend_vm_init(void) 2573 | SPEC_RULE_OBSERVER, 2575, 2576, - 2577 | SPEC_RULE_OP1, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, - 3491, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, + 3486, }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -68592,7 +68260,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 = 2590 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2585 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -68600,7 +68268,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 = 2615 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2610 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -68608,7 +68276,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 = 2640 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2635 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -68619,17 +68287,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 = 2665 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2660 | 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 = 2690 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2685 | 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 = 2715 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2710 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -68640,17 +68308,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 = 2740 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2735 | 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 = 2765 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2760 | 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 = 2790 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2785 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_IDENTICAL: @@ -68661,14 +68329,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 = 2815 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2810 | 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 = 2890 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2885 | 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 = 3115 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3110 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_IDENTICAL: @@ -68679,14 +68347,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 = 2965 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2960 | 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 = 3040 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3035 | 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 = 3120 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3115 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_EQUAL: @@ -68697,12 +68365,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 = 2815 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2810 | 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 = 2890 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2885 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_EQUAL: @@ -68713,12 +68381,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 = 2965 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2960 | 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 = 3040 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3035 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_SMALLER: @@ -68726,12 +68394,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 = 3125 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3120 | 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 = 3200 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3195 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -68739,79 +68407,79 @@ 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 = 3275 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3270 | 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 = 3350 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3345 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_LONG) { - spec = 3437 | SPEC_RULE_OP1; + spec = 3432 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_DOUBLE) { - spec = 3442 | SPEC_RULE_OP1; + spec = 3437 | 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 = 3447 | SPEC_RULE_OP1; + spec = 3442 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3425 | SPEC_RULE_RETVAL; + spec = 3420 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3427 | SPEC_RULE_RETVAL; + spec = 3422 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3429 | SPEC_RULE_RETVAL; + spec = 3424 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3431 | SPEC_RULE_RETVAL; + spec = 3426 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3433; + spec = 3428; } else if (op1_info == MAY_BE_LONG) { - spec = 3434; + spec = 3429; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3435; + spec = 3430; } else if (op1_info == MAY_BE_LONG) { - spec = 3436; + spec = 3431; } break; case ZEND_JMP: if (OP_JMP_ADDR(op, op->op1) > op) { - spec = 2589; + spec = 2584; } break; case ZEND_INIT_FCALL: if (Z_EXTRA_P(RT_CONSTANT(op, op->op2)) != 0) { - spec = 2582; + spec = 2577; } break; case ZEND_RECV: if (op->op2.num == MAY_BE_ANY) { - spec = 2583; + spec = 2578; } 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 = 3487; + spec = 3482; } 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 = 3482 | SPEC_RULE_OP1; + spec = 3477 | 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 = 3489 | SPEC_RULE_RETVAL; + spec = 3484 | SPEC_RULE_RETVAL; } break; case ZEND_FETCH_DIM_R: @@ -68819,22 +68487,22 @@ 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 = 3452 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3447 | 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 = 3488; + spec = 3483; } break; case ZEND_SEND_VAR: if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3477 | SPEC_RULE_OP1; + spec = 3472 | SPEC_RULE_OP1; } break; case ZEND_COUNT: if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 2584 | SPEC_RULE_OP1; + spec = 2579 | SPEC_RULE_OP1; } break; case ZEND_BW_OR: diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index e632a82498637..7f3a3cb5de260 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -1372,506 +1372,502 @@ _(2574, ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER) \ _(2575, ZEND_JMP_FRAMELESS_SPEC_CONST) \ _(2576, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED) \ - _(2577, ZEND_FETCH_INNER_CLASS_SPEC_CONST_CONST) \ - _(2578, ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST) \ - _(2579, ZEND_FETCH_INNER_CLASS_SPEC_TMPVAR_CONST) \ - _(2580, ZEND_FETCH_INNER_CLASS_SPEC_UNUSED_CONST) \ - _(2582, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ - _(2583, ZEND_RECV_NOTYPE_SPEC) \ - _(2585, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ - _(2586, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ - _(2588, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \ - _(2589, ZEND_JMP_FORWARD_SPEC) \ + _(2577, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ + _(2578, ZEND_RECV_NOTYPE_SPEC) \ + _(2580, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ + _(2581, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ + _(2583, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \ + _(2584, ZEND_JMP_FORWARD_SPEC) \ + _(2590, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2591, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2592, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2594, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2595, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(2596, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2597, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2599, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2600, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2601, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2602, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2604, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2610, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2611, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2612, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2614, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2605, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2606, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2607, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2609, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2615, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2616, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2617, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2619, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2620, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ _(2621, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2622, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2624, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2625, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2626, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2627, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2629, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2635, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2636, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2637, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2639, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2630, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2631, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2632, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2634, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2640, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2641, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2642, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2644, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2645, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ _(2646, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2647, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2649, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2650, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2651, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2652, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2654, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2660, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2661, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2662, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2664, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2667, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2669, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2655, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2656, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2657, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2659, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2661, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2662, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2664, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2665, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2667, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2669, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2670, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(2671, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2672, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2674, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2675, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2676, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2677, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2679, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2685, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2686, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2687, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2689, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2691, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2692, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2694, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2680, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2681, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2682, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2684, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2686, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2687, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2689, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2690, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2691, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2692, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2694, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2695, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ _(2696, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2697, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2699, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2700, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2701, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2702, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2704, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2710, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2711, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2712, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2714, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2716, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2717, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2719, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2705, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2706, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2707, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2709, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2711, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2712, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2714, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2715, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2716, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2717, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2719, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2720, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ _(2721, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2722, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2724, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2725, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2726, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2727, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2729, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2735, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2736, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2737, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2739, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2730, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2731, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2732, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2734, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2740, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2741, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2742, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2744, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2745, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ _(2746, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2747, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2749, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2750, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2751, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2752, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2754, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2760, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2761, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2762, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2764, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2755, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2756, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2757, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2759, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2765, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2766, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2767, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2769, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2770, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ _(2771, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2772, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2774, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2775, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2776, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2777, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2779, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2785, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2786, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2787, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2789, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2780, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2781, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2782, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2784, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2790, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2791, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2792, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2794, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2795, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ _(2796, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2797, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2799, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2800, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2801, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2802, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2804, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2810, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2811, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2812, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2814, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2831, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2835, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2836, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2837, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2847, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2849, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2850, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2851, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2852, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2857, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2858, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2859, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2875, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2876, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2877, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2878, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2879, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2880, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2881, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2882, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2883, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2887, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2888, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2889, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2906, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2910, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2911, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2912, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2922, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2924, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2925, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2926, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2927, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2932, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2933, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2934, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2950, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2951, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2952, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2953, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2954, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2955, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2956, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2957, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2958, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2962, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2963, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2964, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2981, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2985, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2986, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2987, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2997, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2999, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3000, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3001, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3002, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3007, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3008, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3009, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3025, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3026, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3027, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3028, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3029, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3030, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3031, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3032, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3033, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3037, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3038, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3039, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3056, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3060, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3061, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3062, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3072, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3074, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3075, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3076, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3077, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3082, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3083, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3084, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3100, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3101, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3102, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3103, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3104, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3105, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3106, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3107, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3108, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3112, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3113, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3114, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3115, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3119, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3120, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3124, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3128, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3129, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3130, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3131, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3132, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3133, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3137, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3138, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3139, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3146, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3153, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3157, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3158, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3159, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3160, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3161, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3162, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3163, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3167, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3168, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3169, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3185, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3186, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3187, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3188, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3189, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3190, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3191, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3192, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3193, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3197, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3198, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3199, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3204, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3206, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3207, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3208, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3221, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3228, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3232, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3233, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3234, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3235, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3236, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3237, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3238, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3242, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3243, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3244, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3260, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3261, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3262, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3263, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3264, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3265, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3266, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3267, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3268, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3272, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3273, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3274, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3279, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3281, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3282, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3283, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3296, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3303, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3307, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3308, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3309, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3310, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3311, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3312, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3313, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3317, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3318, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3319, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3335, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3336, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3337, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3338, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3339, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3340, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3341, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3342, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3343, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3347, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3348, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3349, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3354, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3356, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3357, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3358, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3371, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3378, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3382, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3383, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3384, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3385, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3386, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3387, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3388, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3392, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3393, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3394, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3410, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3411, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3412, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3413, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3414, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3415, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3416, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3417, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3418, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3422, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3423, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3424, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3425, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3426, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3427, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3428, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ - _(3429, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3430, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3431, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3432, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ - _(3433, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3434, ZEND_POST_INC_LONG_SPEC_CV) \ - _(3435, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3436, ZEND_POST_DEC_LONG_SPEC_CV) \ - _(3437, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ - _(3438, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3439, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3441, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3442, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ - _(3443, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3444, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3446, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3447, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ - _(3448, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3449, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3451, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3453, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3454, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(2805, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2806, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2807, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2809, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2825, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2831, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2837, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2841, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_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) \ + _(2846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2847, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2852, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2870, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2871, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2872, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2873, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2874, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2875, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2876, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2877, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2878, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2882, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2883, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2884, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2900, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2906, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2912, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2916, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_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) \ + _(2921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2922, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2927, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2945, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2946, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2947, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2948, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2949, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2950, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2951, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2952, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2953, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2957, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2958, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2959, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2975, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2981, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2987, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2991, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_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) \ + _(2996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2997, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3002, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3020, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3021, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3022, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3023, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3024, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3025, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3026, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3027, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3028, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3032, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3033, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3034, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3050, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3056, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3062, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3066, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_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) \ + _(3071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3072, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3077, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3095, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3096, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3097, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3098, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3099, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3100, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3101, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3102, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3103, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3107, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3108, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3109, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3110, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3114, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3115, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3119, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3123, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3124, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3125, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3126, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3127, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3128, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3132, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3133, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3134, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3135, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3136, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3137, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3138, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3139, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_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) \ + _(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3157, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3158, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3162, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3163, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3164, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3180, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3181, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3182, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3183, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3184, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3185, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3186, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3187, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3188, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3192, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3193, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3194, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3198, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3202, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3207, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3208, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3209, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3211, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_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) \ + _(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3232, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3233, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3237, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3238, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3239, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3255, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3256, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3257, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3258, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3259, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3260, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3261, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3262, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3263, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3267, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3268, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3269, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3273, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3277, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3282, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3283, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3284, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3286, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_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) \ + _(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3307, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3308, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3312, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3313, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3314, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3330, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3331, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3332, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3333, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3334, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3335, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3336, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3337, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3338, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3342, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3343, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3344, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3348, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3352, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3357, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3358, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3359, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3361, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_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) \ + _(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3382, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3383, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3387, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3388, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3389, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3405, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3406, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3407, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3408, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3409, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3410, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3411, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3412, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3413, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3417, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3418, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3419, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3420, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3421, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3422, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3423, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ + _(3424, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3425, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3426, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3427, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ + _(3428, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3429, ZEND_POST_INC_LONG_SPEC_CV) \ + _(3430, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3431, ZEND_POST_DEC_LONG_SPEC_CV) \ + _(3432, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ + _(3433, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3434, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3436, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3437, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ + _(3438, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3439, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3441, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3442, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ + _(3443, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3444, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3446, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3448, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3449, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3451, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3452, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3453, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3454, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3457, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ _(3458, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3459, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3461, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3462, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ - _(3463, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3464, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3466, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3472, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ - _(3473, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3474, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3476, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3479, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ - _(3481, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ - _(3484, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ - _(3486, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ - _(3487, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ - _(3488, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ - _(3489, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ - _(3490, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ - _(3490+1, ZEND_NULL) + _(3467, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3468, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3469, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3471, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3474, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ + _(3476, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ + _(3479, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ + _(3481, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ + _(3482, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ + _(3483, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ + _(3484, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ + _(3485, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ + _(3485+1, ZEND_NULL) diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index b1e6c2950fd6d..202dfd3f734f3 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[211] = { +static const char *zend_vm_opcodes_names[210] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -233,10 +233,9 @@ static const char *zend_vm_opcodes_names[211] = { "ZEND_FRAMELESS_ICALL_3", "ZEND_JMP_FRAMELESS", "ZEND_INIT_PARENT_PROPERTY_HOOK_CALL", - "ZEND_FETCH_INNER_CLASS", }; -static uint32_t zend_vm_opcodes_flags[211] = { +static uint32_t zend_vm_opcodes_flags[210] = { 0x00000000, 0x00000b0b, 0x00000b0b, @@ -447,7 +446,6 @@ static uint32_t zend_vm_opcodes_flags[211] = { 0x00000000, 0x01042003, 0x01001103, - 0x00040307, }; ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(uint8_t opcode) { diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 9734d26ee768e..d472b5b9660f5 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -291,8 +291,7 @@ END_EXTERN_C() #define ZEND_FRAMELESS_ICALL_3 207 #define ZEND_JMP_FRAMELESS 208 #define ZEND_INIT_PARENT_PROPERTY_HOOK_CALL 209 -#define ZEND_FETCH_INNER_CLASS 210 -#define ZEND_VM_LAST_OPCODE 210 +#define ZEND_VM_LAST_OPCODE 209 #endif From e716cc9fd859a51a6df0c30e2abf7c1522538add Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 13:33:24 +0100 Subject: [PATCH 50/65] Revert "defer compiling inner classes" This reverts commit 26b7eb7cdce8a8893cfc3cc9f16d60e950b38ceb. --- Zend/zend_compile.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2222a5f813855..e310573f23801 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -9296,22 +9296,6 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) zend_verify_abstract_class(ce); } - if (inner_class_queue == NULL) { - CG(active_class_entry) = original_ce; - } else { - HashTable *queue = inner_class_queue; - inner_class_queue = NULL; - - ZEND_HASH_FOREACH_PTR(queue, ast) { - zend_compile_class_decl(NULL, ast, 0); - } ZEND_HASH_FOREACH_END(); - - CG(active_class_entry) = original_ce; - - zend_hash_destroy(queue); - FREE_HASHTABLE(queue); - } - if (toplevel) { ce->ce_flags |= ZEND_ACC_TOP_LEVEL; } @@ -9332,7 +9316,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) && !zend_compile_ignore_class(parent_ce, ce->info.user.filename)) { if (zend_try_early_bind(ce, parent_ce, lcname, NULL)) { zend_string_release(lcname); - return; + goto compile_inner_classes; } } } else if (EXPECTED(zend_hash_add_ptr(CG(class_table), lcname, ce) != NULL)) { @@ -9341,7 +9325,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) zend_inheritance_check_override(ce); ce->ce_flags |= ZEND_ACC_LINKED; zend_observer_class_linked_notify(ce, lcname); - return; + goto compile_inner_classes; } else { goto link_unbound; } @@ -9411,6 +9395,24 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) opline->result.opline_num = -1; } } + compile_inner_classes: + + if (inner_class_queue == NULL) { + CG(active_class_entry) = original_ce; + return; + } + + HashTable *queue = inner_class_queue; + inner_class_queue = NULL; + + ZEND_HASH_FOREACH_PTR(queue, ast) { + zend_compile_class_decl(NULL, ast, 0); + } ZEND_HASH_FOREACH_END(); + + CG(active_class_entry) = original_ce; + + zend_hash_destroy(queue); + FREE_HASHTABLE(queue); } /* }}} */ @@ -11701,10 +11703,6 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ zend_compile_use_trait(ast); break; case ZEND_AST_CLASS: - if (CG(active_class_entry)) { - zend_defer_class_decl(ast); - break; - } zend_compile_class_decl(NULL, ast, 0); break; case ZEND_AST_GROUP_USE: From a3abaff10a90fff4a91f2e52aa1bb1bcae8b6134 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 16:42:51 +0100 Subject: [PATCH 51/65] update and fix tests --- Zend/zend_compile.c | 92 ++++++++++++++++++- tests/classes/inner_classes/inheritance.phpt | 8 +- .../inner_classes/simple_declaration_004.phpt | 5 +- .../inner_classes/simple_declaration_005.phpt | 12 +-- 4 files changed, 94 insertions(+), 23 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index e310573f23801..db5e92500b54d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1179,6 +1179,61 @@ static zend_string *zend_resolve_const_name(zend_string *name, uint32_t type, bo name, type, is_fully_qualified, 1, FC(imports_const)); } +static zend_string *get_namespace_from_scope(const zend_class_entry *scope) { + ZEND_ASSERT(scope != NULL); + while (scope && scope->lexical_scope && scope->type != ZEND_NAMESPACE_CLASS) { + scope = scope->lexical_scope; + } + return zend_string_copy(scope->name); +} + +static zend_string *get_scoped_name(zend_string *ns, zend_string *name) { + // remove the matching prefix from name + name = zend_string_tolower(name); + if (ns && ZSTR_LEN(ns) && ZSTR_LEN(name) > ZSTR_LEN(ns) + 1 && + memcmp(ZSTR_VAL(name), ZSTR_VAL(ns), ZSTR_LEN(ns)) == 0 && + ZSTR_VAL(name)[ZSTR_LEN(ns)] == '\\') { + zend_string *ret = zend_string_init(ZSTR_VAL(name) + ZSTR_LEN(ns) + 1, ZSTR_LEN(name) - ZSTR_LEN(ns) - 1, 0); + zend_string_release(name); + return ret; + } + return name; +} + +zend_string *zend_resolve_class_in_scope(zend_string *name, const zend_class_entry *scope) { + zend_string *ns_name = get_namespace_from_scope(scope); + zend_string *original_suffix = get_scoped_name(ns_name, name); + zend_string_release(ns_name); + + const zend_class_entry *current_scope = scope; + + // Traverse upwards in lexical scope, stop at namespace boundary + while (current_scope && current_scope->type != ZEND_NAMESPACE_CLASS) { + // build fully-qualified name: current_scope->name + "\\" + original_suffix + zend_string *try_name = zend_string_concat3( + ZSTR_VAL(current_scope->name), ZSTR_LEN(current_scope->name), + "\\", 1, + ZSTR_VAL(original_suffix), ZSTR_LEN(original_suffix) + ); + + zend_string *lc_try_name = zend_string_tolower(try_name); + + bool has_seen = zend_have_seen_symbol(lc_try_name, ZEND_SYMBOL_CLASS); + zend_string_release(lc_try_name); + + if (has_seen) { + zend_string_release(original_suffix); + return try_name; + } + zend_string_release(try_name); + + current_scope = current_scope->lexical_scope; + } + + zend_string_release(original_suffix); + return NULL; +} + static zend_string *zend_resolve_class_name(zend_string *name, uint32_t type) /* {{{ */ { char *compound; @@ -1237,6 +1292,13 @@ static zend_string *zend_resolve_class_name(zend_string *name, uint32_t type) /* } } + if (CG(active_class_entry)) { + zend_string *import_name = zend_resolve_class_in_scope(name, CG(active_class_entry)); + if (import_name) { + return import_name; + } + } + /* If not fully qualified and not an alias, prepend the current namespace */ return zend_prefix_with_ns(name); } @@ -9139,6 +9201,27 @@ static void zend_defer_class_decl(zend_ast *ast) { zend_hash_next_index_insert_ptr(inner_class_queue, ast); } +static void zend_scan_nested_class_decl(zend_ast *ast) { + ZEND_ASSERT(CG(active_class_entry)); + + const zend_ast_list *list = zend_ast_get_list(ast); + for (int i = 0; i < list->children; i++) { + ast = list->child[i]; + if (ast->kind == ZEND_AST_CLASS) { + const zend_ast_decl *decl = (zend_ast_decl *) ast; + zend_string *name = zend_string_concat3( + ZSTR_VAL(CG(active_class_entry)->name), ZSTR_LEN(CG(active_class_entry)->name), + "\\", 1, + ZSTR_VAL(decl->name), ZSTR_LEN(decl->name) + ); + zend_string *lc_name = zend_string_tolower(name); + zend_register_seen_symbol(lc_name, ZEND_SYMBOL_CLASS); + zend_string_release(name); + zend_string_release(lc_name); + } + } +} + static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) /* {{{ */ { zend_ast_decl *decl = (zend_ast_decl *) ast; @@ -9287,6 +9370,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) zend_enum_register_props(ce); } + zend_scan_nested_class_decl(stmt_ast); zend_compile_stmt(stmt_ast); /* Reset lineno for final opcodes and errors */ @@ -11703,6 +11787,10 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ zend_compile_use_trait(ast); break; case ZEND_AST_CLASS: + if (CG(active_class_entry)) { + zend_defer_class_decl(ast); + break; + } zend_compile_class_decl(NULL, ast, 0); break; case ZEND_AST_GROUP_USE: @@ -11712,10 +11800,6 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ zend_compile_use(ast); break; case ZEND_AST_CONST_DECL: - if (CG(active_class_entry)) { - zend_defer_class_decl(ast); - break; - } zend_compile_const_decl(ast); break; case ZEND_AST_NAMESPACE: diff --git a/tests/classes/inner_classes/inheritance.phpt b/tests/classes/inner_classes/inheritance.phpt index 4f28583c0fc10..a545b6e499e90 100644 --- a/tests/classes/inner_classes/inheritance.phpt +++ b/tests/classes/inner_classes/inheritance.phpt @@ -1,14 +1,12 @@ --TEST-- -inheritance +circular inheritance --FILE-- --EXPECT-- @@ -35,7 +34,5 @@ object(Outer\Middle)#1 (0) { } object(Outer\Middle)#1 (0) { } -object(Outer\Middle)#1 (0) { -} -object(Outer\Middle)#1 (0) { +object(Outer2\Middle)#1 (0) { } diff --git a/tests/classes/inner_classes/simple_declaration_005.phpt b/tests/classes/inner_classes/simple_declaration_005.phpt index b9552de94ec85..49427a492422e 100644 --- a/tests/classes/inner_classes/simple_declaration_005.phpt +++ b/tests/classes/inner_classes/simple_declaration_005.phpt @@ -30,13 +30,5 @@ var_dump(Outer2::testSelf()); var_dump(Outer2::testSelf()); ?> ---EXPECT-- -THIS IS WRONG -object(Outer\Middle)#1 (0) { -} -object(Outer\Middle)#1 (0) { -} -object(Outer\Middle)#1 (0) { -} -object(Outer\Middle)#1 (0) { -} +--EXPECTF-- +Fatal error: Declaration of Outer2::testSelf(): Outer2\middle must be compatible with Outer::testSelf(): Outer\middle in %s on line %d From 28a546625c50de0daa017108d813318b268cc26a Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 18:28:57 +0100 Subject: [PATCH 52/65] handle namespaces properly --- Zend/zend_namespaces.c | 16 ++++------------ Zend/zend_opcode.c | 1 + 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/Zend/zend_namespaces.c b/Zend/zend_namespaces.c index fe061d30866de..1104b55ff6672 100644 --- a/Zend/zend_namespaces.c +++ b/Zend/zend_namespaces.c @@ -28,10 +28,10 @@ static zend_class_entry *global_namespace = NULL; static HashTable namespaces; static zend_class_entry *create_namespace(zend_string *name) { - zend_class_entry *ns = pemalloc(sizeof(zend_class_entry), 1); - memset(ns, 0, sizeof(zend_class_entry)); + zend_class_entry *ns = pecalloc(1, sizeof(zend_class_entry), 1); zend_initialize_class_data(ns, 1); ns->type = ZEND_NAMESPACE_CLASS; + ns->ce_flags |= ZEND_ACC_UNINSTANTIABLE; zend_string *interned_name = zend_new_interned_string(zend_string_copy(name)); ns->name = interned_name; @@ -64,13 +64,12 @@ static zend_class_entry *insert_namespace(const zend_string *name) { zend_string *needle = zend_string_init(ZSTR_VAL(current_ns.s), ZSTR_LEN(current_ns.s), 0); ns = zend_hash_find_ptr(&namespaces, needle); + zend_string_release(part); if (!ns) { ns = create_namespace(needle); ns->parent = parent_ns; - zend_hash_add_ptr(&namespaces, current_ns.s, ns); + zend_hash_add_ptr(&namespaces, zend_string_copy(needle), ns); } - - zend_string_release(part); zend_string_release(needle); parent_ns = ns; @@ -120,12 +119,5 @@ void zend_destroy_namespaces(void) { return; } - zend_class_entry *ns = NULL; - ZEND_HASH_FOREACH_PTR(&namespaces, ns) { - zend_string_release(ns->name); - } ZEND_HASH_FOREACH_END(); - zend_hash_destroy(&namespaces); - zend_string_release(global_namespace->name); - pefree(global_namespace, 1); } diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index b5ed1b7a9bc85..d5bcdc22f8511 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -436,6 +436,7 @@ ZEND_API void destroy_zend_class(zval *zv) } break; case ZEND_INTERNAL_CLASS: + case ZEND_NAMESPACE_CLASS: if (ce->doc_comment) { zend_string_release_ex(ce->doc_comment, 1); } From ab0dd5791682b04455ae48149d1def9b16d37f1e Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 18:47:08 +0100 Subject: [PATCH 53/65] add to windows build --- Zend/zend_namespaces.h | 1 - win32/build/config.w32 | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Zend/zend_namespaces.h b/Zend/zend_namespaces.h index f4030a5090e2c..ce64ce5462e1a 100644 --- a/Zend/zend_namespaces.h +++ b/Zend/zend_namespaces.h @@ -20,7 +20,6 @@ #ifndef ZEND_NAMESPACES_H #define ZEND_NAMESPACES_H -#include "zend.h" #include "zend_compile.h" ZEND_API zend_class_entry *zend_resolve_namespace(zend_string *name); diff --git a/win32/build/config.w32 b/win32/build/config.w32 index f82ed73efe3bd..85efc27c6fb4f 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -240,7 +240,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \ zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c zend_weakrefs.c \ zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c zend_ast.c \ zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_observer.c zend_system_id.c \ - zend_enum.c zend_fibers.c zend_atomic.c zend_hrtime.c zend_frameless_function.c zend_property_hooks.c \ + zend_enum.c zend_fibers.c zend_atomic.c zend_hrtime.c zend_frameless_function.c zend_property_hooks.c zend_namespaces.c \ zend_lazy_objects.c"); ADD_SOURCES("Zend\\Optimizer", "zend_optimizer.c pass1.c pass3.c optimize_func_calls.c block_pass.c optimize_temp_vars_5.c nop_removal.c compact_literals.c zend_cfg.c zend_dfg.c dfa_pass.c zend_ssa.c zend_inference.c zend_func_info.c zend_call_graph.c zend_dump.c escape_analysis.c compact_vars.c dce.c sccp.c scdf.c"); From 7ca157c0d3e1ba63c80be15db716991d47c63c7c Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 19:08:01 +0100 Subject: [PATCH 54/65] fix memory leak --- Zend/zend_namespaces.c | 9 ++++----- tests/classes/inner_classes/reflection_001.phpt | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Zend/zend_namespaces.c b/Zend/zend_namespaces.c index 1104b55ff6672..595b98d4a6e40 100644 --- a/Zend/zend_namespaces.c +++ b/Zend/zend_namespaces.c @@ -27,13 +27,12 @@ static zend_class_entry *global_namespace = NULL; static HashTable namespaces; -static zend_class_entry *create_namespace(zend_string *name) { - zend_class_entry *ns = pecalloc(1, sizeof(zend_class_entry), 1); +static zend_class_entry *create_namespace(zend_string *interned_name) { + zend_class_entry *ns = malloc(sizeof(zend_class_entry)); zend_initialize_class_data(ns, 1); ns->type = ZEND_NAMESPACE_CLASS; ns->ce_flags |= ZEND_ACC_UNINSTANTIABLE; - zend_string *interned_name = zend_new_interned_string(zend_string_copy(name)); ns->name = interned_name; return ns; @@ -61,14 +60,14 @@ static zend_class_entry *insert_namespace(const zend_string *name) { smart_str_appendl(¤t_ns, ZSTR_VAL(part), ZSTR_LEN(part)); smart_str_0(¤t_ns); - zend_string *needle = zend_string_init(ZSTR_VAL(current_ns.s), ZSTR_LEN(current_ns.s), 0); + zend_string *needle = zend_string_init_interned(ZSTR_VAL(current_ns.s), ZSTR_LEN(current_ns.s), 1); ns = zend_hash_find_ptr(&namespaces, needle); zend_string_release(part); if (!ns) { ns = create_namespace(needle); ns->parent = parent_ns; - zend_hash_add_ptr(&namespaces, zend_string_copy(needle), ns); + zend_hash_add_ptr(&namespaces, needle, ns); } zend_string_release(needle); diff --git a/tests/classes/inner_classes/reflection_001.phpt b/tests/classes/inner_classes/reflection_001.phpt index a284c82ebb498..0965778ff190f 100644 --- a/tests/classes/inner_classes/reflection_001.phpt +++ b/tests/classes/inner_classes/reflection_001.phpt @@ -22,8 +22,8 @@ var_dump($ref->isProtected()); var_dump($ref->isPublic()); ?> --EXPECT-- -string(24) "n\s\Outer\Middle\Inner" -string(20) "Outer\Middle\Inner" +string(22) "n\s\Outer\Middle\Inner" +string(5) "Inner" bool(true) bool(false) bool(false) From 416bde23b6bc03d40dd5f74dc13b0eb59ba541ee Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 19:08:42 +0100 Subject: [PATCH 55/65] fixup last commit --- Zend/zend_namespaces.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Zend/zend_namespaces.c b/Zend/zend_namespaces.c index 595b98d4a6e40..f75636d06ff85 100644 --- a/Zend/zend_namespaces.c +++ b/Zend/zend_namespaces.c @@ -69,7 +69,6 @@ static zend_class_entry *insert_namespace(const zend_string *name) { ns->parent = parent_ns; zend_hash_add_ptr(&namespaces, needle, ns); } - zend_string_release(needle); parent_ns = ns; start = pos + 1; From 1143b6ce46bd0f968a30c79c078aa8a750e09694 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 19:20:31 +0100 Subject: [PATCH 56/65] ensure global scope does not have a lexical scope --- Zend/zend_namespaces.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Zend/zend_namespaces.c b/Zend/zend_namespaces.c index f75636d06ff85..33e80028a3c9e 100644 --- a/Zend/zend_namespaces.c +++ b/Zend/zend_namespaces.c @@ -84,6 +84,7 @@ static zend_class_entry *insert_namespace(const zend_string *name) { zend_class_entry *zend_resolve_namespace(zend_string *name) { if (global_namespace == NULL) { global_namespace = create_namespace(zend_empty_string); + global_namespace->lexical_scope = NULL; zend_hash_init(&namespaces, 8, NULL, ZEND_CLASS_DTOR, 1); zend_hash_add_ptr(&namespaces, zend_empty_string, global_namespace); } From 6f10bdaedbaa789198af11aef818fdd011bf4ac1 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 19:40:29 +0100 Subject: [PATCH 57/65] ensure we do not escape class scope boundaries --- Zend/zend_object_handlers.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 9a55c0b6e2168..4e253b9427c98 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -403,7 +403,7 @@ static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *c goto dynamic; } else { wrong: - if (scope && scope->lexical_scope) { + if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) { scope = scope->lexical_scope; goto check_lexical_scope; } @@ -1839,7 +1839,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string * if (zobj->ce->__call) { fbc = zend_get_user_call_function(zobj->ce, method_name); } else { - if (scope && scope->lexical_scope) { + if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) { scope = scope->lexical_scope; goto check_lexical_scope; } @@ -1909,7 +1909,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) { zend_function *fallback_fbc = get_static_method_fallback(ce, function_name); if (!fallback_fbc) { - if (scope && scope->lexical_scope) { + if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) { scope = scope->lexical_scope; goto check_lexical_scope; } @@ -1996,7 +1996,7 @@ ZEND_API zval *zend_std_get_static_property_with_info(zend_class_entry *ce, zend if (UNEXPECTED(property_info->flags & ZEND_ACC_PRIVATE) || UNEXPECTED(!is_protected_compatible_scope(property_info->ce, scope))) { if (type != BP_VAR_IS) { - if (scope && scope->lexical_scope) { + if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) { scope = scope->lexical_scope; goto check_lexical_scope; } @@ -2084,7 +2084,7 @@ ZEND_API zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */ if (UNEXPECTED(constructor->common.scope != scope)) { if (UNEXPECTED(constructor->op_array.fn_flags & ZEND_ACC_PRIVATE) || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(constructor), scope))) { - if (scope && scope->lexical_scope) { + if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) { scope = scope->lexical_scope; goto check_lexical_scope; } From 226adc4d5a1d6f4829d789e27f369c04dc45f962 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 19:46:09 +0100 Subject: [PATCH 58/65] move namespace destruction to end of process --- Zend/zend.c | 5 +++++ main/main.c | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index 2d8a0f455f8b4..5304da5922923 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -18,6 +18,9 @@ */ #include "zend.h" + +#include + #include "zend_extensions.h" #include "zend_modules.h" #include "zend_constants.h" @@ -1223,6 +1226,8 @@ void zend_shutdown(void) /* {{{ */ zend_map_ptr_static_last = 0; zend_map_ptr_static_size = 0; + zend_destroy_namespaces(); + zend_destroy_rsrc_list_dtors(); zend_unload_modules(); diff --git a/main/main.c b/main/main.c index 82f3960d36754..415cb02185e94 100644 --- a/main/main.c +++ b/main/main.c @@ -66,8 +66,6 @@ #include #endif -#include - #include "zend_compile.h" #include "zend_execute.h" #include "zend_highlight.h" @@ -1968,8 +1966,6 @@ void php_request_shutdown(void *dummy) zend_post_deactivate_modules(); } zend_end_try(); - zend_destroy_namespaces(); - /* 12. SAPI related shutdown*/ zend_try { sapi_deactivate_module(); From 4ac9b822329770f36af8103ae8a8116d49768397 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 19:52:03 +0100 Subject: [PATCH 59/65] remove dangling grammar --- Zend/zend_language_parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 0328e6b367e8c..b4f5ff789db74 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -276,7 +276,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars %type lexical_var_list encaps_list %type array_pair non_empty_array_pair_list array_pair_list possible_array_pair -%type isset_variable type return_type type_expr type_without_static inner_type_without_static +%type isset_variable type return_type type_expr type_without_static %type identifier type_expr_without_static union_type_without_static_element union_type_without_static intersection_type_without_static %type inline_function union_type_element union_type intersection_type %type attributed_statement attributed_class_statement attributed_parameter From 0ccd2157a47770b25a1c3c77a36136be9c51abc9 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 21:51:14 +0100 Subject: [PATCH 60/65] make a copy of the empty string --- Zend/zend_namespaces.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_namespaces.c b/Zend/zend_namespaces.c index 33e80028a3c9e..d1d258bee029d 100644 --- a/Zend/zend_namespaces.c +++ b/Zend/zend_namespaces.c @@ -83,7 +83,7 @@ static zend_class_entry *insert_namespace(const zend_string *name) { zend_class_entry *zend_resolve_namespace(zend_string *name) { if (global_namespace == NULL) { - global_namespace = create_namespace(zend_empty_string); + global_namespace = create_namespace(zend_string_copy(zend_empty_string)); global_namespace->lexical_scope = NULL; zend_hash_init(&namespaces, 8, NULL, ZEND_CLASS_DTOR, 1); zend_hash_add_ptr(&namespaces, zend_empty_string, global_namespace); From 9579c43e2033d67cec74d9291fdb583b2c602955 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 21:58:41 +0100 Subject: [PATCH 61/65] ensure namespaces are not used after free --- Zend/zend.c | 4 ++-- Zend/zend_namespaces.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index 5304da5922923..b209938f6343b 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1226,13 +1226,13 @@ void zend_shutdown(void) /* {{{ */ zend_map_ptr_static_last = 0; zend_map_ptr_static_size = 0; - zend_destroy_namespaces(); - zend_destroy_rsrc_list_dtors(); zend_unload_modules(); zend_optimizer_shutdown(); + + zend_destroy_namespaces(); startup_done = false; } /* }}} */ diff --git a/Zend/zend_namespaces.c b/Zend/zend_namespaces.c index d1d258bee029d..bfcbd2f43d2e4 100644 --- a/Zend/zend_namespaces.c +++ b/Zend/zend_namespaces.c @@ -119,4 +119,5 @@ void zend_destroy_namespaces(void) { } zend_hash_destroy(&namespaces); + global_namespace = NULL; } From 0a68147113c93b159754b8ccf6739867b02ab9cc Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Tue, 25 Mar 2025 23:59:45 +0100 Subject: [PATCH 62/65] tighten up namespaces --- Zend/zend_namespaces.c | 24 ++++++------------------ tests/classes/.idea/deployment.xml | 2 +- tests/classes/.idea/php.xml | 20 +------------------- 3 files changed, 8 insertions(+), 38 deletions(-) diff --git a/Zend/zend_namespaces.c b/Zend/zend_namespaces.c index bfcbd2f43d2e4..b5eea162402f7 100644 --- a/Zend/zend_namespaces.c +++ b/Zend/zend_namespaces.c @@ -33,7 +33,7 @@ static zend_class_entry *create_namespace(zend_string *interned_name) { ns->type = ZEND_NAMESPACE_CLASS; ns->ce_flags |= ZEND_ACC_UNINSTANTIABLE; - ns->name = interned_name; + ns->name = zend_string_copy(interned_name); return ns; } @@ -41,43 +41,31 @@ static zend_class_entry *create_namespace(zend_string *interned_name) { static zend_class_entry *insert_namespace(const zend_string *name) { zend_class_entry *ns = NULL; zend_class_entry *parent_ns = global_namespace; - zend_string *part = NULL; const char *start = ZSTR_VAL(name); const char *end = start + ZSTR_LEN(name); const char *pos = start; size_t len = 0; - smart_str current_ns = {0}; - while (pos <= end) { if (pos == end || *pos == '\\') { len = pos - start; - part = zend_string_init(start, len, 0); - - if (current_ns.s) { - smart_str_appendc(¤t_ns, '\\'); - } - smart_str_appendl(¤t_ns, ZSTR_VAL(part), ZSTR_LEN(part)); - smart_str_0(¤t_ns); + zend_string *needle = zend_string_init(ZSTR_VAL(name), len, 1); - zend_string *needle = zend_string_init_interned(ZSTR_VAL(current_ns.s), ZSTR_LEN(current_ns.s), 1); ns = zend_hash_find_ptr(&namespaces, needle); - zend_string_release(part); if (!ns) { - ns = create_namespace(needle); + zend_string *interned_name = zend_new_interned_string(needle); + ns = create_namespace(interned_name); ns->parent = parent_ns; - zend_hash_add_ptr(&namespaces, needle, ns); + zend_hash_add_ptr(&namespaces, interned_name, ns); } + zend_string_release(needle); parent_ns = ns; - start = pos + 1; } pos++; } - smart_str_free(¤t_ns); - return ns; } diff --git a/tests/classes/.idea/deployment.xml b/tests/classes/.idea/deployment.xml index a1b58348df6f7..b36a3a03fcca8 100644 --- a/tests/classes/.idea/deployment.xml +++ b/tests/classes/.idea/deployment.xml @@ -1,6 +1,6 @@ - + diff --git a/tests/classes/.idea/php.xml b/tests/classes/.idea/php.xml index c41a634129307..860f567da6214 100644 --- a/tests/classes/.idea/php.xml +++ b/tests/classes/.idea/php.xml @@ -1,22 +1,4 @@ - - - - - - - - - - - - + \ No newline at end of file From a65d578f921b6e9e8b4c7bba40ccf24f50bdcd57 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Wed, 26 Mar 2025 00:12:00 +0100 Subject: [PATCH 63/65] finally fix the elusive memory leak --- Zend/zend.c | 3 --- Zend/zend_namespaces.c | 2 +- main/main.c | 3 +++ 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index b209938f6343b..b79a04a9e1f59 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -19,8 +19,6 @@ #include "zend.h" -#include - #include "zend_extensions.h" #include "zend_modules.h" #include "zend_constants.h" @@ -1232,7 +1230,6 @@ void zend_shutdown(void) /* {{{ */ zend_optimizer_shutdown(); - zend_destroy_namespaces(); startup_done = false; } /* }}} */ diff --git a/Zend/zend_namespaces.c b/Zend/zend_namespaces.c index b5eea162402f7..b415ce61fa995 100644 --- a/Zend/zend_namespaces.c +++ b/Zend/zend_namespaces.c @@ -49,7 +49,7 @@ static zend_class_entry *insert_namespace(const zend_string *name) { while (pos <= end) { if (pos == end || *pos == '\\') { len = pos - start; - zend_string *needle = zend_string_init(ZSTR_VAL(name), len, 1); + zend_string *needle = zend_string_init(ZSTR_VAL(name), len, 0); ns = zend_hash_find_ptr(&namespaces, needle); diff --git a/main/main.c b/main/main.c index 415cb02185e94..1fa39a675ce5d 100644 --- a/main/main.c +++ b/main/main.c @@ -66,6 +66,8 @@ #include #endif +#include "zend_namespaces.h" + #include "zend_compile.h" #include "zend_execute.h" #include "zend_highlight.h" @@ -1956,6 +1958,7 @@ void php_request_shutdown(void *dummy) } zend_end_try(); /* 9. Shutdown scanner/executor/compiler and restore ini entries */ + zend_destroy_namespaces(); zend_deactivate(); /* 10. free request-bound globals */ From 7275681b0b9041c1f469e45fb3fef8ee7afcd95d Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Wed, 26 Mar 2025 01:12:14 +0100 Subject: [PATCH 64/65] stupid errors --- Zend/zend.c | 3 +++ Zend/zend_opcode.c | 4 ---- main/main.c | 3 --- tests/classes/.idea/.gitignore | 8 -------- tests/classes/.idea/classes.iml | 8 -------- tests/classes/.idea/deployment.xml | 14 -------------- tests/classes/.idea/misc.xml | 7 ------- tests/classes/.idea/modules.xml | 8 -------- tests/classes/.idea/php.xml | 4 ---- tests/classes/.idea/vcs.xml | 6 ------ 10 files changed, 3 insertions(+), 62 deletions(-) delete mode 100644 tests/classes/.idea/.gitignore delete mode 100644 tests/classes/.idea/classes.iml delete mode 100644 tests/classes/.idea/deployment.xml delete mode 100644 tests/classes/.idea/misc.xml delete mode 100644 tests/classes/.idea/modules.xml delete mode 100644 tests/classes/.idea/php.xml delete mode 100644 tests/classes/.idea/vcs.xml diff --git a/Zend/zend.c b/Zend/zend.c index b79a04a9e1f59..03e67534a1e21 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -42,6 +42,7 @@ #include "Optimizer/zend_optimizer.h" #include "php.h" #include "php_globals.h" +#include "zend_namespaces.h" // FIXME: Breaks the declaration of the function below #undef zenderror @@ -1348,6 +1349,8 @@ ZEND_API void zend_deactivate(void) /* {{{ */ shutdown_scanner(); } zend_end_try(); + zend_destroy_namespaces(); + /* shutdown_executor() takes care of its own bailout handling */ shutdown_executor(); diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index d5bcdc22f8511..20b2d70cdec1a 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -430,10 +430,6 @@ ZEND_API void destroy_zend_class(zval *zv) if (ce->backed_enum_table) { zend_hash_release(ce->backed_enum_table); } - if (ce->required_scope) { - ce->required_scope->refcount--; - ce->required_scope = NULL; - } break; case ZEND_INTERNAL_CLASS: case ZEND_NAMESPACE_CLASS: diff --git a/main/main.c b/main/main.c index 1fa39a675ce5d..415cb02185e94 100644 --- a/main/main.c +++ b/main/main.c @@ -66,8 +66,6 @@ #include #endif -#include "zend_namespaces.h" - #include "zend_compile.h" #include "zend_execute.h" #include "zend_highlight.h" @@ -1958,7 +1956,6 @@ void php_request_shutdown(void *dummy) } zend_end_try(); /* 9. Shutdown scanner/executor/compiler and restore ini entries */ - zend_destroy_namespaces(); zend_deactivate(); /* 10. free request-bound globals */ diff --git a/tests/classes/.idea/.gitignore b/tests/classes/.idea/.gitignore deleted file mode 100644 index 13566b81b018a..0000000000000 --- a/tests/classes/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/tests/classes/.idea/classes.iml b/tests/classes/.idea/classes.iml deleted file mode 100644 index bf4c9d396a05d..0000000000000 --- a/tests/classes/.idea/classes.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/tests/classes/.idea/deployment.xml b/tests/classes/.idea/deployment.xml deleted file mode 100644 index b36a3a03fcca8..0000000000000 --- a/tests/classes/.idea/deployment.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/classes/.idea/misc.xml b/tests/classes/.idea/misc.xml deleted file mode 100644 index d7a613f20d021..0000000000000 --- a/tests/classes/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/tests/classes/.idea/modules.xml b/tests/classes/.idea/modules.xml deleted file mode 100644 index 02630dad86b5a..0000000000000 --- a/tests/classes/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/tests/classes/.idea/php.xml b/tests/classes/.idea/php.xml deleted file mode 100644 index 860f567da6214..0000000000000 --- a/tests/classes/.idea/php.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/tests/classes/.idea/vcs.xml b/tests/classes/.idea/vcs.xml deleted file mode 100644 index c8ade07fc487e..0000000000000 --- a/tests/classes/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 13f130ea6b359ee1f07b06ac99a80bbd0396ff2c Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Wed, 26 Mar 2025 01:33:56 +0100 Subject: [PATCH 65/65] destroy namespaces after executor shutdown --- Zend/zend.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index 03e67534a1e21..8180869b785ee 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1349,11 +1349,11 @@ ZEND_API void zend_deactivate(void) /* {{{ */ shutdown_scanner(); } zend_end_try(); - zend_destroy_namespaces(); - /* shutdown_executor() takes care of its own bailout handling */ shutdown_executor(); + zend_destroy_namespaces(); + zend_try { zend_ini_deactivate(); } zend_end_try();