Merge branch 'PHP-7.4'

This commit is contained in:
Nikita Popov 2019-06-11 13:15:03 +02:00
commit e4fae9c061
44 changed files with 1792 additions and 1312 deletions

View file

@ -10,4 +10,4 @@ var_dump($a instanceOf A);
echo "ok\n"; echo "ok\n";
?> ?>
--EXPECTF-- --EXPECTF--
Fatal error: Interface 'RecurisiveFooFar' not found in %sbug30922.php on line %d Fatal error: Interface RecurisiveFooFar cannot implement itself in %s on line %d

View file

@ -0,0 +1,37 @@
--TEST--
Class order allowed with autoloading (1)
--FILE--
<?php
spl_autoload_register(function($class) {
if ($class === 'A') {
class A {
public function method() : B {}
}
var_dump(new A);
} else if ($class == 'B') {
class B extends A {
public function method() : C {}
}
var_dump(new B);
} else {
class C extends B {
}
var_dump(new C);
}
});
var_dump(new C);
?>
===DONE===
--EXPECT--
object(A)#2 (0) {
}
object(B)#2 (0) {
}
object(C)#2 (0) {
}
object(C)#2 (0) {
}
===DONE===

View file

@ -0,0 +1,38 @@
--TEST--
Class order allowed with autoloading (2)
--FILE--
<?php
spl_autoload_register(function($class) {
if ($class === 'A') {
class A {
public function method() : B {}
}
var_dump(new A);
} else if ($class == 'B') {
class B extends A {
public function method() : C {}
}
var_dump(new B);
} else {
class C extends B {
}
var_dump(new C);
}
});
// Same as autoload1 test case, but with a different autoloading root
var_dump(new B);
?>
===DONE===
--EXPECT--
object(A)#2 (0) {
}
object(C)#2 (0) {
}
object(B)#2 (0) {
}
object(B)#2 (0) {
}
===DONE===

View file

@ -0,0 +1,45 @@
--TEST--
Class order allowed with autoloading (3)
--FILE--
<?php
spl_autoload_register(function($class) {
if ($class == 'A') {
class A {
public function method(): X {}
}
var_dump(new A);
} else if ($class == 'B') {
class B extends A {
public function method(): Y {}
}
var_dump(new B);
} else if ($class == 'X') {
class X {
public function method(): A {}
}
var_dump(new X);
} else if ($class == 'Y') {
class Y extends X {
public function method(): B {}
}
var_dump(new Y);
}
});
var_dump(new B);
?>
===DONE===
--EXPECT--
object(A)#2 (0) {
}
object(X)#2 (0) {
}
object(Y)#2 (0) {
}
object(B)#2 (0) {
}
object(B)#2 (0) {
}
===DONE===

View file

@ -0,0 +1,44 @@
--TEST--
Class order allowed with autoloading (4)
--FILE--
<?php
// Same as autoload3 test case, but with X, Y being interfaces.
spl_autoload_register(function($class) {
if ($class == 'A') {
class A {
public function method(): X {}
}
var_dump(new A);
} else if ($class == 'B') {
class B extends A {
public function method(): Y {}
}
var_dump(new B);
} else if ($class == 'X') {
interface X {
public function method(): A;
}
var_dump(interface_exists('X'));
} else if ($class == 'Y') {
interface Y extends X {
public function method(): B;
}
var_dump(interface_exists('Y'));
}
});
var_dump(new B);
?>
===DONE===
--EXPECT--
object(A)#2 (0) {
}
bool(true)
bool(true)
object(B)#2 (0) {
}
object(B)#2 (0) {
}
===DONE===

View file

@ -0,0 +1,60 @@
--TEST--
Class order allowed with autoloading (5)
--FILE--
<?php
// Similar to variance3, but one more class hierarchy in the cycle
spl_autoload_register(function($class) {
if ($class == 'A') {
class A {
public function method(): X {}
}
var_dump(new A);
} else if ($class == 'B') {
class B extends A {
public function method(): Y {}
}
var_dump(new B);
} else if ($class == 'X') {
class X {
public function method(): Q {}
}
var_dump(new X);
} else if ($class == 'Y') {
class Y extends X {
public function method(): R {}
}
var_dump(new Y);
} else if ($class == 'Q') {
class Q {
public function method(): A {}
}
var_dump(new Q);
} else if ($class == 'R') {
class R extends Q {
public function method(): B {}
}
var_dump(new R);
}
});
var_dump(new B);
?>
===DONE===
--EXPECT--
object(A)#2 (0) {
}
object(X)#2 (0) {
}
object(Q)#2 (0) {
}
object(R)#2 (0) {
}
object(Y)#2 (0) {
}
object(B)#2 (0) {
}
object(B)#2 (0) {
}
===DONE===

View file

@ -1,16 +1,16 @@
--TEST-- --TEST--
Returns are covariant, but we don't allow the code due to class ordering (autoload variation) Variance error in the presence of autoloading (1)
--FILE-- --FILE--
<?php <?php
spl_autoload_register(function($class) { spl_autoload_register(function($class) {
if ($class === 'A') { if ($class === 'A') {
class A { class A {
public function method() : B {} public function method() : C {}
} }
} else if ($class == 'B') { } else if ($class == 'B') {
class B extends A { class B extends A {
public function method() : C {} public function method() : B {}
} }
} else { } else {
class C extends B { class C extends B {
@ -18,8 +18,8 @@ spl_autoload_register(function($class) {
} }
}); });
$c = new C; $b = new B;
?> ?>
--EXPECTF-- --EXPECTF--
Fatal error: Could not check compatibility between B::method(): C and A::method(): B, because class C is not available in %s on line %d Fatal error: Declaration of B::method(): B must be compatible with A::method(): C in %s on line %d

View file

@ -0,0 +1,27 @@
--TEST--
Variance error in the presence of autoloading (2)
--FILE--
<?php
// Same as autoload_error1, but for argument types.
spl_autoload_register(function($class) {
if ($class === 'A') {
class A {
public function method(B $x) {}
}
} else if ($class == 'B') {
class B extends A {
public function method(C $x) {}
}
} else {
class C extends B {
}
}
});
$b = new B;
$c = new C;
?>
--EXPECTF--
Fatal error: Declaration of B::method(C $x) must be compatible with A::method(B $x) in %s on line %d

View file

@ -0,0 +1,38 @@
--TEST--
Variance error in the presence of autoloading (3)
--FILE--
<?php
spl_autoload_register(function($class) {
if ($class == 'A') {
class A {
public function method(): X {}
}
} else if ($class == 'B') {
class B extends A {
public function method(): Y {}
}
} else if ($class == 'X') {
class X {
public function method(): Q {}
}
} else if ($class == 'Y') {
class Y extends X {
public function method(): R {}
}
} else if ($class == 'Q') {
class Q {
public function method(): B {}
}
} else if ($class == 'R') {
class R extends Q {
public function method(): A {}
}
}
});
$b = new B;
?>
--EXPECTF--
Fatal error: Declaration of R::method(): A must be compatible with Q::method(): B in %s on line %d

View file

@ -0,0 +1,39 @@
--TEST--
Variance error in the presence of autoloading (4)
--FILE--
<?php
spl_autoload_register(function($class) {
if ($class == 'A') {
class A {
public function method(): X {}
}
var_dump(new A);
} else if ($class == 'B') {
class B extends A {
public function method(): Y {}
}
var_dump(new B);
} else if ($class == 'X') {
class X {
public function method(): B {}
}
var_dump(new X);
} else if ($class == 'Y') {
class Y extends X {
public function method(): A {}
}
var_dump(new Y);
}
});
var_dump(new B);
?>
--EXPECTF--
object(A)#2 (0) {
}
object(X)#2 (0) {
}
Fatal error: Declaration of Y::method(): A must be compatible with X::method(): B in %s on line %d

View file

@ -0,0 +1,44 @@
--TEST--
Variance error in the presence of autoloading (5)
--FILE--
<?php
spl_autoload_register(function($class) {
if ($class == 'A') {
class A {
public function method(): X {}
}
var_dump(new A);
} else if ($class == 'B') {
class B extends A {
public function method(): Y {}
}
var_dump(new B);
} else if ($class == 'X') {
class X {
public function method(Y $a) {}
}
var_dump(new X);
} else if ($class == 'Y') {
class Y extends X {
public function method(Z $a) {}
}
var_dump(new Y);
} else if ($class == 'Z') {
class Z extends Y {
public function method($a) {}
}
var_dump(new Z);
}
});
var_dump(new B);
?>
--EXPECTF--
object(A)#2 (0) {
}
object(X)#2 (0) {
}
Fatal error: Declaration of Y::method(Z $a) must be compatible with X::method(Y $a) in %s on line %d

View file

@ -0,0 +1,39 @@
--TEST--
Variance error in the presence of autoloading (6)
--FILE--
<?php
spl_autoload_register(function($class) {
if ($class == 'A') {
class A {
public function method(): X {}
}
var_dump(new A);
} else if ($class == 'B') {
class B extends A {
public function method(): Y {}
}
var_dump(new B);
} else if ($class == 'X') {
class X {
public function method(): X {}
}
var_dump(new X);
} else if ($class == 'Y') {
class Y extends X {
public function method(): Unknown {}
}
var_dump(new Y);
}
});
var_dump(new B);
?>
--EXPECTF--
object(A)#2 (0) {
}
object(X)#2 (0) {
}
Fatal error: Could not check compatibility between Y::method(): Unknown and X::method(): X, because class Unknown is not available in %s on line %d

View file

@ -2506,7 +2506,7 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class
class_entry->type = ZEND_INTERNAL_CLASS; class_entry->type = ZEND_INTERNAL_CLASS;
zend_initialize_class_data(class_entry, 0); zend_initialize_class_data(class_entry, 0);
class_entry->ce_flags = ce_flags | ZEND_ACC_CONSTANTS_UPDATED | ZEND_ACC_LINKED; class_entry->ce_flags = ce_flags | ZEND_ACC_CONSTANTS_UPDATED | ZEND_ACC_LINKED | ZEND_ACC_RESOLVED_PARENT | ZEND_ACC_RESOLVED_INTERFACES;
class_entry->info.internal.module = EG(current_module); class_entry->info.internal.module = EG(current_module);
if (class_entry->info.internal.builtin_functions) { if (class_entry->info.internal.builtin_functions) {

View file

@ -370,6 +370,9 @@ void init_compiler(void) /* {{{ */
zend_hash_init(&CG(filenames_table), 8, NULL, ZVAL_PTR_DTOR, 0); zend_hash_init(&CG(filenames_table), 8, NULL, ZVAL_PTR_DTOR, 0);
zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0); zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0);
CG(unclean_shutdown) = 0; CG(unclean_shutdown) = 0;
CG(delayed_variance_obligations) = NULL;
CG(delayed_autoloads) = NULL;
} }
/* }}} */ /* }}} */
@ -379,6 +382,17 @@ void shutdown_compiler(void) /* {{{ */
zend_stack_destroy(&CG(delayed_oplines_stack)); zend_stack_destroy(&CG(delayed_oplines_stack));
zend_hash_destroy(&CG(filenames_table)); zend_hash_destroy(&CG(filenames_table));
zend_arena_destroy(CG(arena)); zend_arena_destroy(CG(arena));
if (CG(delayed_variance_obligations)) {
zend_hash_destroy(CG(delayed_variance_obligations));
FREE_HASHTABLE(CG(delayed_variance_obligations));
CG(delayed_variance_obligations) = NULL;
}
if (CG(delayed_autoloads)) {
zend_hash_destroy(CG(delayed_autoloads));
FREE_HASHTABLE(CG(delayed_autoloads));
CG(delayed_autoloads) = NULL;
}
} }
/* }}} */ /* }}} */
@ -1033,7 +1047,7 @@ ZEND_API int do_bind_function(zval *lcname) /* {{{ */
} }
/* }}} */ /* }}} */
ZEND_API int do_bind_class(zval *lcname, zend_class_entry *parent_ce) /* {{{ */ ZEND_API int do_bind_class(zval *lcname) /* {{{ */
{ {
zend_class_entry *ce; zend_class_entry *ce;
zval *rtd_key, *zv; zval *rtd_key, *zv;
@ -1060,7 +1074,7 @@ ZEND_API int do_bind_class(zval *lcname, zend_class_entry *parent_ce) /* {{{ */
return FAILURE; return FAILURE;
} }
zend_do_link_class(ce, parent_ce); zend_do_link_class(ce);
return SUCCESS; return SUCCESS;
} }
/* }}} */ /* }}} */
@ -1103,7 +1117,7 @@ ZEND_API uint32_t zend_build_delayed_early_binding_list(const zend_op_array *op_
zend_op *end = opline + op_array->last; zend_op *end = opline + op_array->last;
while (opline < end) { while (opline < end) {
if (opline->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED) { if (opline->opcode == ZEND_DECLARE_CLASS_DELAYED) {
*prev_opline_num = opline - op_array->opcodes; *prev_opline_num = opline - op_array->opcodes;
prev_opline_num = &opline->result.opline_num; prev_opline_num = &opline->result.opline_num;
} }
@ -1126,11 +1140,10 @@ ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array, uint3
while (opline_num != (uint32_t)-1) { while (opline_num != (uint32_t)-1) {
const zend_op *opline = &op_array->opcodes[opline_num]; const zend_op *opline = &op_array->opcodes[opline_num];
zval *lcname = RT_CONSTANT(opline, opline->op1); zval *lcname = RT_CONSTANT(opline, opline->op1);
zval *parent_name = RT_CONSTANT(opline, opline->op2);
zend_class_entry *ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(lcname + 1)); zend_class_entry *ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(lcname + 1));
zend_class_entry *parent_ce = zend_lookup_class_ex(Z_STR_P(parent_name), Z_STR_P(parent_name + 1), 0); zend_class_entry *parent_ce = zend_lookup_class(ce->parent_name);
if (ce && parent_ce && zend_can_early_bind(ce, parent_ce)) { if (ce && parent_ce && zend_can_early_bind(ce, parent_ce)) {
do_bind_class(lcname, parent_ce); do_bind_class(lcname);
} }
opline_num = op_array->opcodes[opline_num].result.opline_num; opline_num = op_array->opcodes[opline_num].result.opline_num;
} }
@ -6321,15 +6334,9 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
LITERAL_STR(opline->op1, lcname); LITERAL_STR(opline->op1, lcname);
if (decl->flags & ZEND_ACC_ANON_CLASS) { if (decl->flags & ZEND_ACC_ANON_CLASS) {
opline->opcode = ZEND_DECLARE_ANON_CLASS;
opline->result_type = IS_VAR; opline->result_type = IS_VAR;
opline->result.var = get_temporary_variable(); opline->result.var = get_temporary_variable();
if (extends_ast) {
opline->opcode = ZEND_DECLARE_ANON_INHERITED_CLASS;
opline->op2_type = IS_CONST;
opline->op2.constant = zend_add_class_name_literal(zend_string_copy(ce->parent_name));
} else {
opline->opcode = ZEND_DECLARE_ANON_CLASS;
}
if (!zend_hash_add_ptr(CG(class_table), lcname, ce)) { if (!zend_hash_add_ptr(CG(class_table), lcname, ce)) {
/* this anonymous class has been included */ /* this anonymous class has been included */
@ -6345,22 +6352,16 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
zend_add_literal_string(&key); zend_add_literal_string(&key);
zend_hash_update_ptr(CG(class_table), key, ce); zend_hash_update_ptr(CG(class_table), key, ce);
if (extends_ast) { opline->opcode = ZEND_DECLARE_CLASS;
if (toplevel if (extends_ast && toplevel
&& (CG(compiler_options) & ZEND_COMPILE_DELAYED_BINDING) && (CG(compiler_options) & ZEND_COMPILE_DELAYED_BINDING)
/* We currently don't early-bind classes that implement interfaces or use traits */ /* We currently don't early-bind classes that implement interfaces or use traits */
&& !(ce->ce_flags & (ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) { && !(ce->ce_flags & (ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))
CG(active_op_array)->fn_flags |= ZEND_ACC_EARLY_BINDING; ) {
opline->opcode = ZEND_DECLARE_INHERITED_CLASS_DELAYED; CG(active_op_array)->fn_flags |= ZEND_ACC_EARLY_BINDING;
opline->result_type = IS_UNUSED; opline->opcode = ZEND_DECLARE_CLASS_DELAYED;
opline->result.opline_num = -1; opline->result_type = IS_UNUSED;
} else { opline->result.opline_num = -1;
opline->opcode = ZEND_DECLARE_INHERITED_CLASS;
}
opline->op2_type = IS_CONST;
opline->op2.constant = zend_add_class_name_literal(zend_string_copy(ce->parent_name));
} else {
opline->opcode = ZEND_DECLARE_CLASS;
} }
} }
return opline; return opline;

View file

@ -269,8 +269,14 @@ typedef struct _zend_oparray_context {
/* Children must reuse parent get_iterator() | | | */ /* Children must reuse parent get_iterator() | | | */
#define ZEND_ACC_REUSE_GET_ITERATOR (1 << 18) /* X | | | */ #define ZEND_ACC_REUSE_GET_ITERATOR (1 << 18) /* X | | | */
/* | | | */ /* | | | */
/* Class is being linked. Don't free strings. | | | */ /* Parent class is resolved (CE). | | | */
#define ZEND_ACC_LINKING_IN_PROGRESS (1 << 19) /* X | | | */ #define ZEND_ACC_RESOLVED_PARENT (1 << 19) /* X | | | */
/* | | | */
/* Interfaces are resolved (CEs). | | | */
#define ZEND_ACC_RESOLVED_INTERFACES (1 << 20) /* X | | | */
/* | | | */
/* Class has unresolved variance obligations. | | | */
#define ZEND_ACC_UNRESOLVED_VARIANCE (1 << 21) /* X | | | */
/* | | | */ /* | | | */
/* Function Flags (unused: 28...30) | | | */ /* Function Flags (unused: 28...30) | | | */
/* ============== | | | */ /* ============== | | | */
@ -291,7 +297,7 @@ typedef struct _zend_oparray_context {
#define ZEND_ACC_HAS_FINALLY_BLOCK (1 << 15) /* | X | | */ #define ZEND_ACC_HAS_FINALLY_BLOCK (1 << 15) /* | X | | */
/* | | | */ /* | | | */
/* "main" op_array with | | | */ /* "main" op_array with | | | */
/* ZEND_DECLARE_INHERITED_CLASS_DELAYED opcodes | | | */ /* ZEND_DECLARE_CLASS_DELAYED opcodes | | | */
#define ZEND_ACC_EARLY_BINDING (1 << 16) /* | X | | */ #define ZEND_ACC_EARLY_BINDING (1 << 16) /* | X | | */
/* | | | */ /* | | | */
/* call through user function trampoline. e.g. | | | */ /* call through user function trampoline. e.g. | | | */
@ -741,7 +747,7 @@ zend_bool zend_handle_encoding_declaration(zend_ast *ast);
void zend_do_free(znode *op1); void zend_do_free(znode *op1);
ZEND_API int do_bind_function(zval *lcname); ZEND_API int do_bind_function(zval *lcname);
ZEND_API int do_bind_class(zval *lcname, zend_class_entry *parent_ce); ZEND_API int do_bind_class(zval *lcname);
ZEND_API uint32_t zend_build_delayed_early_binding_list(const zend_op_array *op_array); ZEND_API uint32_t zend_build_delayed_early_binding_list(const zend_op_array *op_array);
ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array, uint32_t first_early_binding_opline); ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array, uint32_t first_early_binding_opline);
@ -848,6 +854,7 @@ void zend_assert_valid_class_name(const zend_string *const_name);
#define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80 #define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80
#define ZEND_FETCH_CLASS_SILENT 0x0100 #define ZEND_FETCH_CLASS_SILENT 0x0100
#define ZEND_FETCH_CLASS_EXCEPTION 0x0200 #define ZEND_FETCH_CLASS_EXCEPTION 0x0200
#define ZEND_FETCH_CLASS_ALLOW_UNLINKED 0x0400
#define ZEND_PARAM_REF (1<<0) #define ZEND_PARAM_REF (1<<0)
#define ZEND_PARAM_VARIADIC (1<<1) #define ZEND_PARAM_VARIADIC (1<<1)
@ -1024,7 +1031,7 @@ END_EXTERN_C()
* may apper in run-time */ * may apper in run-time */
#define ZEND_COMPILE_IGNORE_INTERNAL_CLASSES (1<<4) #define ZEND_COMPILE_IGNORE_INTERNAL_CLASSES (1<<4)
/* generate ZEND_DECLARE_INHERITED_CLASS_DELAYED opcode to delay early binding */ /* generate ZEND_DECLARE_CLASS_DELAYED opcode to delay early binding */
#define ZEND_COMPILE_DELAYED_BINDING (1<<5) #define ZEND_COMPILE_DELAYED_BINDING (1<<5)
/* disable constant substitution at compile-time */ /* disable constant substitution at compile-time */

View file

@ -34,6 +34,7 @@
#include "zend_vm.h" #include "zend_vm.h"
#include "zend_float.h" #include "zend_float.h"
#include "zend_weakrefs.h" #include "zend_weakrefs.h"
#include "zend_inheritance.h"
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif #endif
@ -862,7 +863,8 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *
zend_string_release_ex(lc_name, 0); zend_string_release_ex(lc_name, 0);
} }
ce = (zend_class_entry*)Z_PTR_P(zv); ce = (zend_class_entry*)Z_PTR_P(zv);
if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_LINKED))) { if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_LINKED)) &&
!(flags & ZEND_FETCH_CLASS_ALLOW_UNLINKED)) {
return NULL; return NULL;
} }
return ce; return ce;

View file

@ -124,6 +124,9 @@ struct _zend_compiler_globals {
void *map_ptr_base; void *map_ptr_base;
size_t map_ptr_size; size_t map_ptr_size;
size_t map_ptr_last; size_t map_ptr_last;
HashTable *delayed_variance_obligations;
HashTable *delayed_autoloads;
}; };

View file

@ -26,6 +26,10 @@
#include "zend_smart_str.h" #include "zend_smart_str.h"
#include "zend_operators.h" #include "zend_operators.h"
static void add_dependency_obligation(zend_class_entry *ce, zend_class_entry *dependency_ce);
static void add_compatibility_obligation(
zend_class_entry *ce, const zend_function *child_fn, const zend_function *parent_fn);
static void overridden_ptr_dtor(zval *zv) /* {{{ */ static void overridden_ptr_dtor(zval *zv) /* {{{ */
{ {
efree_size(Z_PTR_P(zv), sizeof(zend_function)); efree_size(Z_PTR_P(zv), sizeof(zend_function));
@ -174,7 +178,7 @@ static zend_string *resolve_class_name(const zend_function *fe, zend_string *nam
zend_class_entry *ce = fe->common.scope; zend_class_entry *ce = fe->common.scope;
ZEND_ASSERT(ce); ZEND_ASSERT(ce);
if (zend_string_equals_literal_ci(name, "parent") && ce->parent) { if (zend_string_equals_literal_ci(name, "parent") && ce->parent) {
if (ce->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS)) { if (ce->ce_flags & ZEND_ACC_RESOLVED_PARENT) {
return ce->parent->name; return ce->parent->name;
} else { } else {
return ce->parent_name; return ce->parent_name;
@ -199,32 +203,75 @@ static zend_bool class_visible(zend_class_entry *ce) {
static zend_class_entry *lookup_class(const zend_function *fe, zend_string *name) { static zend_class_entry *lookup_class(const zend_function *fe, zend_string *name) {
zend_class_entry *ce; zend_class_entry *ce;
if (!CG(in_compilation)) { if (!CG(in_compilation)) {
ce = zend_lookup_class(name); uint32_t flags = ZEND_FETCH_CLASS_ALLOW_UNLINKED | ZEND_FETCH_CLASS_NO_AUTOLOAD;
ce = zend_lookup_class_ex(name, NULL, flags);
if (ce) { if (ce) {
return ce; return ce;
} }
/* We'll autoload this class and process delayed variance obligations later. */
if (!CG(delayed_autoloads)) {
ALLOC_HASHTABLE(CG(delayed_autoloads));
zend_hash_init(CG(delayed_autoloads), 0, NULL, NULL, 0);
}
zend_hash_add_empty_element(CG(delayed_autoloads), name);
} else { } else {
ce = zend_lookup_class_ex(name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD); ce = zend_lookup_class_ex(name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD);
if (ce && class_visible(ce)) { if (ce && class_visible(ce)) {
return ce; return ce;
} }
}
/* The current class may not be registered yet, so check for it explicitly. */ /* The current class may not be registered yet, so check for it explicitly. */
if (zend_string_equals_ci(fe->common.scope->name, name)) { if (zend_string_equals_ci(fe->common.scope->name, name)) {
return fe->common.scope; return fe->common.scope;
}
} }
return NULL; return NULL;
} }
/* Instanceof that's safe to use on unlinked classes. For the unlinked case, we only handle /* Instanceof that's safe to use on unlinked classes. */
* class identity here. */
static zend_bool unlinked_instanceof(zend_class_entry *ce1, zend_class_entry *ce2) { static zend_bool unlinked_instanceof(zend_class_entry *ce1, zend_class_entry *ce2) {
if ((ce1->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS))) { zend_class_entry *ce;
if (ce1 == ce2) {
return 1;
}
if (ce1->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_RESOLVED_INTERFACES)) {
return instanceof_function(ce1, ce2); return instanceof_function(ce1, ce2);
} }
return ce1 == ce2;
ce = ce1;
while (ce->parent) {
if (ce->ce_flags & ZEND_ACC_RESOLVED_PARENT) {
ce = ce->parent;
} else {
ce = zend_lookup_class_ex(ce->parent_name, NULL,
ZEND_FETCH_CLASS_ALLOW_UNLINKED | ZEND_FETCH_CLASS_NO_AUTOLOAD);
if (!ce) {
break;
}
}
if (ce == ce2) {
return 1;
}
}
if (ce1->num_interfaces) {
uint32_t i;
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_RESOLVED_INTERFACES));
for (i = 0; i < ce1->num_interfaces; i++) {
ce = zend_lookup_class_ex(
ce1->interface_names[i].name, ce1->interface_names[i].lc_name,
ZEND_FETCH_CLASS_ALLOW_UNLINKED | ZEND_FETCH_CLASS_NO_AUTOLOAD);
if (ce && unlinked_instanceof(ce, ce2)) {
return 1;
}
}
}
return 0;
} }
/* Unresolved means that class declarations that are currently not available are needed to /* Unresolved means that class declarations that are currently not available are needed to
@ -261,13 +308,14 @@ static inheritance_status zend_perform_covariant_type_check(
return INHERITANCE_SUCCESS; return INHERITANCE_SUCCESS;
} }
/* Make sure to always load both classes, to avoid only registering one of them as
* a delayed autoload. */
fe_ce = lookup_class(fe, fe_class_name); fe_ce = lookup_class(fe, fe_class_name);
proto_ce = lookup_class(proto, proto_class_name);
if (!fe_ce) { if (!fe_ce) {
*unresolved_class = fe_class_name; *unresolved_class = fe_class_name;
return INHERITANCE_UNRESOLVED; return INHERITANCE_UNRESOLVED;
} }
proto_ce = lookup_class(proto, proto_class_name);
if (!proto_ce) { if (!proto_ce) {
*unresolved_class = proto_class_name; *unresolved_class = proto_class_name;
return INHERITANCE_UNRESOLVED; return INHERITANCE_UNRESOLVED;
@ -440,6 +488,16 @@ static inheritance_status zend_do_perform_implementation_check(
} }
/* }}} */ /* }}} */
static inheritance_status perform_delayable_implementation_check(
zend_string **unresolved_class, zend_class_entry *ce,
const zend_function *fe, const zend_function *proto) {
inheritance_status status = zend_do_perform_implementation_check(unresolved_class, fe, proto);
if (status == INHERITANCE_UNRESOLVED) {
add_compatibility_obligation(ce, fe, proto);
}
return status;
}
static ZEND_COLD void zend_append_type_hint(smart_str *str, const zend_function *fptr, zend_arg_info *arg_info, int return_hint) /* {{{ */ static ZEND_COLD void zend_append_type_hint(smart_str *str, const zend_function *fptr, zend_arg_info *arg_info, int return_hint) /* {{{ */
{ {
@ -601,12 +659,12 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function
} }
/* }}} */ /* }}} */
static zend_always_inline uint32_t func_lineno(zend_function *fn) { static zend_always_inline uint32_t func_lineno(const zend_function *fn) {
return fn->common.type == ZEND_USER_FUNCTION ? fn->op_array.line_start : 0; return fn->common.type == ZEND_USER_FUNCTION ? fn->op_array.line_start : 0;
} }
static void ZEND_COLD emit_incompatible_method_error( static void ZEND_COLD emit_incompatible_method_error(
zend_function *child, zend_function *parent, const zend_function *child, const zend_function *parent,
inheritance_status status, zend_string *unresolved_class) { inheritance_status status, zend_string *unresolved_class) {
zend_string *parent_prototype = zend_get_function_declaration(parent); zend_string *parent_prototype = zend_get_function_declaration(parent);
zend_string *child_prototype = zend_get_function_declaration(child); zend_string *child_prototype = zend_get_function_declaration(child);
@ -707,8 +765,8 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
ZEND_FN_SCOPE_NAME(child), ZSTR_VAL(child->common.function_name), zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); ZEND_FN_SCOPE_NAME(child), ZSTR_VAL(child->common.function_name), zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
} }
status = zend_do_perform_implementation_check(&unresolved_class, child, parent); status = perform_delayable_implementation_check(&unresolved_class, ce, child, parent);
if (status != INHERITANCE_SUCCESS) { if (status == INHERITANCE_ERROR) {
emit_incompatible_method_error(child, parent, status, unresolved_class); emit_incompatible_method_error(child, parent, status, unresolved_class);
} }
} }
@ -887,6 +945,7 @@ static void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_en
ce->interfaces[ce->num_interfaces++] = entry; ce->interfaces[ce->num_interfaces++] = entry;
} }
} }
ce->ce_flags |= ZEND_ACC_RESOLVED_INTERFACES;
/* and now call the implementing handlers */ /* and now call the implementing handlers */
while (ce_num < ce->num_interfaces) { while (ce_num < ce->num_interfaces) {
@ -988,6 +1047,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
zend_string_release_ex(ce->parent_name, 0); zend_string_release_ex(ce->parent_name, 0);
} }
ce->parent = parent_ce; ce->parent = parent_ce;
ce->ce_flags |= ZEND_ACC_RESOLVED_PARENT;
/* Inherit interfaces */ /* Inherit interfaces */
if (parent_ce->num_interfaces) { if (parent_ce->num_interfaces) {
@ -1297,10 +1357,11 @@ static void zend_do_implement_interfaces(zend_class_entry *ce) /* {{{ */
} }
for (i = 0; i < ce->num_interfaces; i++) { for (i = 0; i < ce->num_interfaces; i++) {
iface = zend_fetch_class_by_name(ce->interface_names[i].name, iface = zend_fetch_class_by_name(
ce->interface_names[i].lc_name, ZEND_FETCH_CLASS_INTERFACE); ce->interface_names[i].name, ce->interface_names[i].lc_name,
if (UNEXPECTED(iface == NULL)) { ZEND_FETCH_CLASS_INTERFACE|ZEND_FETCH_CLASS_ALLOW_UNLINKED);
return; if (!(iface->ce_flags & ZEND_ACC_LINKED)) {
add_dependency_obligation(ce, iface);
} }
if (UNEXPECTED(!(iface->ce_flags & ZEND_ACC_INTERFACE))) { if (UNEXPECTED(!(iface->ce_flags & ZEND_ACC_INTERFACE))) {
efree(interfaces); efree(interfaces);
@ -1337,6 +1398,7 @@ static void zend_do_implement_interfaces(zend_class_entry *ce) /* {{{ */
ce->num_interfaces = num_interfaces; ce->num_interfaces = num_interfaces;
ce->interfaces = interfaces; ce->interfaces = interfaces;
ce->ce_flags |= ZEND_ACC_RESOLVED_INTERFACES;
i = ce->parent ? ce->parent->num_interfaces : 0; i = ce->parent ? ce->parent->num_interfaces : 0;
for (; i < ce->num_interfaces; i++) { for (; i < ce->num_interfaces; i++) {
@ -1423,18 +1485,18 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s
if ((existing_fn = zend_hash_find_ptr(*overridden, key)) != NULL) { if ((existing_fn = zend_hash_find_ptr(*overridden, key)) != NULL) {
if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) { if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
/* Make sure the trait method is compatible with previosly declared abstract method */ /* Make sure the trait method is compatible with previosly declared abstract method */
status = zend_do_perform_implementation_check( status = perform_delayable_implementation_check(
&unresolved_class, fn, existing_fn); &unresolved_class, ce, fn, existing_fn);
if (status != INHERITANCE_SUCCESS) { if (status == INHERITANCE_ERROR) {
emit_incompatible_method_error( emit_incompatible_method_error(
fn, existing_fn, status, unresolved_class); fn, existing_fn, status, unresolved_class);
} }
} }
if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
/* Make sure the abstract declaration is compatible with previous declaration */ /* Make sure the abstract declaration is compatible with previous declaration */
status = zend_do_perform_implementation_check( status = perform_delayable_implementation_check(
&unresolved_class, existing_fn, fn); &unresolved_class, ce, existing_fn, fn);
if (status != INHERITANCE_SUCCESS) { if (status == INHERITANCE_ERROR) {
emit_incompatible_method_error( emit_incompatible_method_error(
existing_fn, fn, status, unresolved_class); existing_fn, fn, status, unresolved_class);
} }
@ -1450,14 +1512,14 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s
} else if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT && } else if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT &&
(existing_fn->common.scope->ce_flags & ZEND_ACC_INTERFACE) == 0) { (existing_fn->common.scope->ce_flags & ZEND_ACC_INTERFACE) == 0) {
/* Make sure the trait method is compatible with previosly declared abstract method */ /* Make sure the trait method is compatible with previosly declared abstract method */
status = zend_do_perform_implementation_check(&unresolved_class, fn, existing_fn); status = perform_delayable_implementation_check(&unresolved_class, ce, fn, existing_fn);
if (status != INHERITANCE_SUCCESS) { if (status == INHERITANCE_ERROR) {
emit_incompatible_method_error(fn, existing_fn, status, unresolved_class); emit_incompatible_method_error(fn, existing_fn, status, unresolved_class);
} }
} else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { } else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
/* Make sure the abstract declaration is compatible with previous declaration */ /* Make sure the abstract declaration is compatible with previous declaration */
status = zend_do_perform_implementation_check(&unresolved_class, existing_fn, fn); status = perform_delayable_implementation_check(&unresolved_class, ce, existing_fn, fn);
if (status != INHERITANCE_SUCCESS) { if (status == INHERITANCE_ERROR) {
emit_incompatible_method_error(existing_fn, fn, status, unresolved_class); emit_incompatible_method_error(existing_fn, fn, status, unresolved_class);
} }
return; return;
@ -2071,10 +2133,167 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */
} }
/* }}} */ /* }}} */
ZEND_API void zend_do_link_class(zend_class_entry *ce, zend_class_entry *parent) /* {{{ */ typedef struct {
enum { OBLIGATION_DEPENDENCY, OBLIGATION_COMPATIBILITY } type;
union {
zend_class_entry *dependency_ce;
struct {
const zend_function *parent_fn;
const zend_function *child_fn;
};
};
} variance_obligation;
static void variance_obligation_dtor(zval *zv) {
efree(Z_PTR_P(zv));
}
static void variance_obligation_ht_dtor(zval *zv) {
zend_hash_destroy(Z_PTR_P(zv));
FREE_HASHTABLE(Z_PTR_P(zv));
}
static HashTable *get_or_init_obligations_for_class(zend_class_entry *ce) {
HashTable *ht;
zend_ulong key;
if (!CG(delayed_variance_obligations)) {
ALLOC_HASHTABLE(CG(delayed_variance_obligations));
zend_hash_init(CG(delayed_variance_obligations), 0, NULL, variance_obligation_ht_dtor, 0);
}
key = (zend_ulong) (uintptr_t) ce;
ht = zend_hash_index_find_ptr(CG(delayed_variance_obligations), key);
if (ht) {
return ht;
}
ALLOC_HASHTABLE(ht);
zend_hash_init(ht, 0, NULL, variance_obligation_dtor, 0);
zend_hash_index_add_new_ptr(CG(delayed_variance_obligations), key, ht);
ce->ce_flags |= ZEND_ACC_UNRESOLVED_VARIANCE;
return ht;
}
static void add_dependency_obligation(zend_class_entry *ce, zend_class_entry *dependency_ce) {
HashTable *obligations = get_or_init_obligations_for_class(ce);
variance_obligation *obligation = emalloc(sizeof(variance_obligation));
obligation->type = OBLIGATION_DEPENDENCY;
obligation->dependency_ce = dependency_ce;
zend_hash_next_index_insert_ptr(obligations, obligation);
}
static void add_compatibility_obligation(
zend_class_entry *ce, const zend_function *child_fn, const zend_function *parent_fn) {
HashTable *obligations = get_or_init_obligations_for_class(ce);
variance_obligation *obligation = emalloc(sizeof(variance_obligation));
obligation->type = OBLIGATION_COMPATIBILITY;
obligation->child_fn = child_fn;
obligation->parent_fn = parent_fn;
zend_hash_next_index_insert_ptr(obligations, obligation);
}
static void resolve_delayed_variance_obligations(zend_class_entry *ce);
static int check_variance_obligation(zval *zv) {
variance_obligation *obligation = Z_PTR_P(zv);
if (obligation->type == OBLIGATION_DEPENDENCY) {
zend_class_entry *dependency_ce = obligation->dependency_ce;
if (dependency_ce->ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE) {
resolve_delayed_variance_obligations(dependency_ce);
}
if (!(dependency_ce->ce_flags & ZEND_ACC_LINKED)) {
return ZEND_HASH_APPLY_KEEP;
}
} else {
zend_string *unresolved_class;
inheritance_status status = zend_do_perform_implementation_check(
&unresolved_class, obligation->child_fn, obligation->parent_fn);
if (status == INHERITANCE_UNRESOLVED) {
return ZEND_HASH_APPLY_KEEP;
}
if (status == INHERITANCE_ERROR) {
emit_incompatible_method_error(
obligation->child_fn, obligation->parent_fn, status, unresolved_class);
}
/* Either the compatibility check was successful or only threw a warning. */
}
return ZEND_HASH_APPLY_REMOVE;
}
static void load_delayed_classes() {
HashTable *delayed_autoloads = CG(delayed_autoloads);
zend_string *name;
if (!delayed_autoloads) {
return;
}
/* Take ownership of this HT, to avoid concurrent modification during autoloading. */
CG(delayed_autoloads) = NULL;
ZEND_HASH_FOREACH_STR_KEY(delayed_autoloads, name) {
zend_lookup_class(name);
} ZEND_HASH_FOREACH_END();
zend_hash_destroy(delayed_autoloads);
FREE_HASHTABLE(delayed_autoloads);
}
static void resolve_delayed_variance_obligations(zend_class_entry *ce) {
HashTable *all_obligations = CG(delayed_variance_obligations), *obligations;
zend_ulong num_key = (zend_ulong) (uintptr_t) ce;
ZEND_ASSERT(all_obligations != NULL);
obligations = zend_hash_index_find_ptr(all_obligations, num_key);
ZEND_ASSERT(obligations != NULL);
zend_hash_apply(obligations, check_variance_obligation);
if (zend_hash_num_elements(obligations) == 0) {
ce->ce_flags &= ~ZEND_ACC_UNRESOLVED_VARIANCE;
ce->ce_flags |= ZEND_ACC_LINKED;
zend_hash_index_del(all_obligations, num_key);
}
}
static void report_variance_errors(zend_class_entry *ce) {
HashTable *all_obligations = CG(delayed_variance_obligations), *obligations;
variance_obligation *obligation;
zend_ulong num_key = (zend_ulong) (uintptr_t) ce;
ZEND_ASSERT(all_obligations != NULL);
obligations = zend_hash_index_find_ptr(all_obligations, num_key);
ZEND_ASSERT(obligations != NULL);
ZEND_HASH_FOREACH_PTR(obligations, obligation) {
inheritance_status status;
zend_string *unresolved_class;
/* There should not be any unresolved parents at this point. */
ZEND_ASSERT(obligation->type == OBLIGATION_COMPATIBILITY);
/* Just used to fetch the unresolved_class in this case. */
status = zend_do_perform_implementation_check(
&unresolved_class, obligation->child_fn, obligation->parent_fn);
ZEND_ASSERT(status == INHERITANCE_UNRESOLVED);
emit_incompatible_method_error(
obligation->child_fn, obligation->parent_fn, status, unresolved_class);
} ZEND_HASH_FOREACH_END();
/* Only warnings were thrown above -- that means that there are incompatibilities, but only
* ones that we permit. Mark all classes with open obligations as fully linked. */
ce->ce_flags &= ~ZEND_ACC_UNRESOLVED_VARIANCE;
ce->ce_flags |= ZEND_ACC_LINKED;
zend_hash_index_del(all_obligations, num_key);
}
ZEND_API void zend_do_link_class(zend_class_entry *ce) /* {{{ */
{ {
ce->ce_flags |= ZEND_ACC_LINKING_IN_PROGRESS; if (ce->parent_name) {
if (parent) { zend_class_entry *parent = zend_fetch_class_by_name(
ce->parent_name, NULL, ZEND_FETCH_CLASS_ALLOW_UNLINKED);
if (!(parent->ce_flags & ZEND_ACC_LINKED)) {
add_dependency_obligation(ce, parent);
}
zend_do_inheritance(ce, parent); zend_do_inheritance(ce, parent);
} }
if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) { if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) {
@ -2088,8 +2307,19 @@ ZEND_API void zend_do_link_class(zend_class_entry *ce, zend_class_entry *parent)
} }
zend_build_properties_info_table(ce); zend_build_properties_info_table(ce);
ce->ce_flags &= ~ZEND_ACC_LINKING_IN_PROGRESS;
ce->ce_flags |= ZEND_ACC_LINKED; if (!(ce->ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE)) {
ce->ce_flags |= ZEND_ACC_LINKED;
return;
}
load_delayed_classes();
if (ce->ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE) {
resolve_delayed_variance_obligations(ce);
if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
report_variance_errors(ce);
}
}
} }
/* Check whether early binding is prevented due to unresolved types in inheritance checks. */ /* Check whether early binding is prevented due to unresolved types in inheritance checks. */

View file

@ -27,7 +27,7 @@ BEGIN_EXTERN_C()
ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface); ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface);
ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce); ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce);
ZEND_API void zend_do_link_class(zend_class_entry *ce, zend_class_entry *parent_ce); ZEND_API void zend_do_link_class(zend_class_entry *ce);
void zend_verify_abstract_class(zend_class_entry *ce); void zend_verify_abstract_class(zend_class_entry *ce);
void zend_build_properties_info_table(zend_class_entry *ce); void zend_build_properties_info_table(zend_class_entry *ce);

View file

@ -292,7 +292,7 @@ static int zend_implement_traversable(zend_class_entry *interface, zend_class_en
return SUCCESS; return SUCCESS;
} }
if (class_type->num_interfaces) { if (class_type->num_interfaces) {
ZEND_ASSERT(class_type->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS)); ZEND_ASSERT(class_type->ce_flags & ZEND_ACC_RESOLVED_INTERFACES);
for (i = 0; i < class_type->num_interfaces; i++) { for (i = 0; i < class_type->num_interfaces; i++) {
if (class_type->interfaces[i] == zend_ce_aggregate || class_type->interfaces[i] == zend_ce_iterator) { if (class_type->interfaces[i] == zend_ce_aggregate || class_type->interfaces[i] == zend_ce_iterator) {
return SUCCESS; return SUCCESS;
@ -322,7 +322,7 @@ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entr
} else if (class_type->get_iterator != zend_user_it_get_new_iterator) { } else if (class_type->get_iterator != zend_user_it_get_new_iterator) {
/* c-level get_iterator cannot be changed (exception being only Traversable is implemented) */ /* c-level get_iterator cannot be changed (exception being only Traversable is implemented) */
if (class_type->num_interfaces) { if (class_type->num_interfaces) {
ZEND_ASSERT(class_type->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS)); ZEND_ASSERT(class_type->ce_flags & ZEND_ACC_RESOLVED_INTERFACES);
for (i = 0; i < class_type->num_interfaces; i++) { for (i = 0; i < class_type->num_interfaces; i++) {
if (class_type->interfaces[i] == zend_ce_iterator) { if (class_type->interfaces[i] == zend_ce_iterator) {
zend_error_noreturn(E_ERROR, "Class %s cannot implement both %s and %s at the same time", zend_error_noreturn(E_ERROR, "Class %s cannot implement both %s and %s at the same time",

View file

@ -238,7 +238,7 @@ ZEND_API void destroy_zend_class(zval *zv)
} }
switch (ce->type) { switch (ce->type) {
case ZEND_USER_CLASS: case ZEND_USER_CLASS:
if (ce->parent_name && !(ce->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS))) { if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_RESOLVED_PARENT)) {
zend_string_release_ex(ce->parent_name, 0); zend_string_release_ex(ce->parent_name, 0);
} }
if (ce->default_properties_table) { if (ce->default_properties_table) {
@ -298,7 +298,7 @@ ZEND_API void destroy_zend_class(zval *zv)
} }
zend_hash_destroy(&ce->constants_table); zend_hash_destroy(&ce->constants_table);
if (ce->num_interfaces > 0) { if (ce->num_interfaces > 0) {
if (!(ce->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS))) { if (!(ce->ce_flags & ZEND_ACC_RESOLVED_INTERFACES)) {
uint32_t i; uint32_t i;
for (i = 0; i < ce->num_interfaces; i++) { for (i = 0; i < ce->num_interfaces; i++) {
@ -585,7 +585,6 @@ static void emit_live_range(
/* Classes don't have to be destroyed. */ /* Classes don't have to be destroyed. */
case ZEND_FETCH_CLASS: case ZEND_FETCH_CLASS:
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
/* FAST_CALLs don't have to be destroyed. */ /* FAST_CALLs don't have to be destroyed. */
case ZEND_FAST_CALL: case ZEND_FAST_CALL:
return; return;
@ -957,7 +956,6 @@ ZEND_API int pass_two(zend_op_array *op_array)
break; break;
} }
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
/* absolute index to relative offset */ /* absolute index to relative offset */

View file

@ -2265,7 +2265,7 @@ static zend_bool ZEND_FASTCALL instanceof_interface_only(const zend_class_entry
uint32_t i; uint32_t i;
if (instance_ce->num_interfaces) { if (instance_ce->num_interfaces) {
ZEND_ASSERT(instance_ce->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS)); ZEND_ASSERT(instance_ce->ce_flags & ZEND_ACC_RESOLVED_INTERFACES);
for (i = 0; i < instance_ce->num_interfaces; i++) { for (i = 0; i < instance_ce->num_interfaces; i++) {
if (instanceof_interface_only(instance_ce->interfaces[i], ce)) { if (instanceof_interface_only(instance_ce->interfaces[i], ce)) {
return 1; return 1;
@ -2293,7 +2293,7 @@ static zend_bool ZEND_FASTCALL instanceof_interface(const zend_class_entry *inst
uint32_t i; uint32_t i;
if (instance_ce->num_interfaces) { if (instance_ce->num_interfaces) {
ZEND_ASSERT(instance_ce->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_LINKING_IN_PROGRESS)); ZEND_ASSERT(instance_ce->ce_flags & ZEND_ACC_RESOLVED_INTERFACES);
for (i = 0; i < instance_ce->num_interfaces; i++) { for (i = 0; i < instance_ce->num_interfaces; i++) {
if (instanceof_interface(instance_ce->interfaces[i], ce)) { if (instanceof_interface(instance_ce->interfaces[i], ce)) {
return 1; return 1;

View file

@ -7122,45 +7122,20 @@ ZEND_VM_HANDLER(139, ZEND_DECLARE_CLASS, CONST, ANY)
USE_OPLINE USE_OPLINE
SAVE_OPLINE(); SAVE_OPLINE();
do_bind_class(RT_CONSTANT(opline, opline->op1), NULL); do_bind_class(RT_CONSTANT(opline, opline->op1));
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} }
ZEND_VM_HANDLER(140, ZEND_DECLARE_INHERITED_CLASS, CONST, CONST) ZEND_VM_HANDLER(145, ZEND_DECLARE_CLASS_DELAYED, CONST, ANY)
{
zend_class_entry *parent;
USE_OPLINE
SAVE_OPLINE();
parent = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)),
Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1),
ZEND_FETCH_CLASS_EXCEPTION);
if (UNEXPECTED(parent == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
do_bind_class(RT_CONSTANT(opline, opline->op1), parent);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, CONST, CONST)
{ {
USE_OPLINE USE_OPLINE
zval *zce, *orig_zce; zval *zce, *orig_zce;
zend_class_entry *parent;
SAVE_OPLINE(); SAVE_OPLINE();
if ((zce = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1)) == NULL || if ((zce = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1)) == NULL ||
((orig_zce = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)+1), 1)) != NULL && ((orig_zce = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)+1), 1)) != NULL &&
Z_CE_P(zce) != Z_CE_P(orig_zce))) { Z_CE_P(zce) != Z_CE_P(orig_zce))) {
parent = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), do_bind_class(RT_CONSTANT(opline, opline->op1));
Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1),
ZEND_FETCH_CLASS_EXCEPTION);
if (UNEXPECTED(parent == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
do_bind_class(RT_CONSTANT(opline, opline->op1), parent);
} }
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} }
@ -7181,36 +7156,7 @@ ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ANY, ANY, JMP_ADDR)
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE(); ZEND_VM_CONTINUE();
} }
zend_do_link_class(ce, NULL); zend_do_link_class(ce);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(172, ZEND_DECLARE_ANON_INHERITED_CLASS, CONST, CONST, JMP_ADDR)
{
zval *zv;
zend_class_entry *ce, *parent;
USE_OPLINE
SAVE_OPLINE();
zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
ZEND_ASSERT(zv != NULL);
ce = Z_CE_P(zv);
Z_CE_P(EX_VAR(opline->result.var)) = ce;
if (ce->ce_flags & ZEND_ACC_LINKED) {
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE();
}
parent = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)),
Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1),
ZEND_FETCH_CLASS_EXCEPTION);
if (UNEXPECTED(parent == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
zend_do_link_class(ce, parent);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} }
@ -7406,7 +7352,6 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
case ZEND_FETCH_CLASS: case ZEND_FETCH_CLASS:
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
break; /* return value is zend_class_entry pointer */ break; /* return value is zend_class_entry pointer */
default: default:

View file

@ -2090,7 +2090,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLE
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE(); ZEND_VM_CONTINUE();
} }
zend_do_link_class(ce, NULL); zend_do_link_class(ce);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} }
@ -2237,7 +2237,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(
case ZEND_FETCH_CLASS: case ZEND_FETCH_CLASS:
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
break; /* return value is zend_class_entry pointer */ break; /* return value is zend_class_entry pointer */
default: default:
@ -4011,7 +4010,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_SPEC_CONST_HANDL
USE_OPLINE USE_OPLINE
SAVE_OPLINE(); SAVE_OPLINE();
do_bind_class(RT_CONSTANT(opline, opline->op1), NULL); do_bind_class(RT_CONSTANT(opline, opline->op1));
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *zce, *orig_zce;
SAVE_OPLINE();
if ((zce = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1)) == NULL ||
((orig_zce = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)+1), 1)) != NULL &&
Z_CE_P(zce) != Z_CE_P(orig_zce))) {
do_bind_class(RT_CONSTANT(opline, opline->op1));
}
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} }
@ -6141,74 +6154,6 @@ array_key_exists_array:
} }
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */ /* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_INHERITED_CLASS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_class_entry *parent;
USE_OPLINE
SAVE_OPLINE();
parent = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)),
Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1),
ZEND_FETCH_CLASS_EXCEPTION);
if (UNEXPECTED(parent == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
do_bind_class(RT_CONSTANT(opline, opline->op1), parent);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *zce, *orig_zce;
zend_class_entry *parent;
SAVE_OPLINE();
if ((zce = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1)) == NULL ||
((orig_zce = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)+1), 1)) != NULL &&
Z_CE_P(zce) != Z_CE_P(orig_zce))) {
parent = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)),
Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1),
ZEND_FETCH_CLASS_EXCEPTION);
if (UNEXPECTED(parent == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
do_bind_class(RT_CONSTANT(opline, opline->op1), parent);
}
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zval *zv;
zend_class_entry *ce, *parent;
USE_OPLINE
SAVE_OPLINE();
zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
ZEND_ASSERT(zv != NULL);
ce = Z_CE_P(zv);
Z_CE_P(EX_VAR(opline->result.var)) = ce;
if (ce->ce_flags & ZEND_ACC_LINKED) {
ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
ZEND_VM_CONTINUE();
}
parent = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)),
Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1),
ZEND_FETCH_CLASS_EXCEPTION);
if (UNEXPECTED(parent == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
zend_do_link_class(ce, parent);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{ {
USE_OPLINE USE_OPLINE
@ -55682,7 +55627,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
(void*)&&ZEND_INSTANCEOF_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_INSTANCEOF_SPEC_CV_UNUSED_LABEL,
(void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_DECLARE_CLASS_SPEC_CONST_LABEL, (void*)&&ZEND_DECLARE_CLASS_SPEC_CONST_LABEL,
(void*)&&ZEND_DECLARE_INHERITED_CLASS_SPEC_CONST_CONST_LABEL,
(void*)&&ZEND_DECLARE_FUNCTION_SPEC_LABEL, (void*)&&ZEND_DECLARE_FUNCTION_SPEC_LABEL,
(void*)&&ZEND_YIELD_FROM_SPEC_CONST_LABEL, (void*)&&ZEND_YIELD_FROM_SPEC_CONST_LABEL,
(void*)&&ZEND_YIELD_FROM_SPEC_TMP_LABEL, (void*)&&ZEND_YIELD_FROM_SPEC_TMP_LABEL,
@ -55690,7 +55634,7 @@ ZEND_API void execute_ex(zend_execute_data *ex)
(void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_YIELD_FROM_SPEC_CV_LABEL, (void*)&&ZEND_YIELD_FROM_SPEC_CV_LABEL,
(void*)&&ZEND_DECLARE_CONST_SPEC_CONST_CONST_LABEL, (void*)&&ZEND_DECLARE_CONST_SPEC_CONST_CONST_LABEL,
(void*)&&ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_CONST_CONST_LABEL, (void*)&&ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_LABEL,
(void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL,
@ -56045,7 +55989,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
(void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_SPACESHIP_SPEC_CV_CV_LABEL, (void*)&&ZEND_SPACESHIP_SPEC_CV_CV_LABEL,
(void*)&&ZEND_DECLARE_ANON_CLASS_SPEC_LABEL, (void*)&&ZEND_DECLARE_ANON_CLASS_SPEC_LABEL,
(void*)&&ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_CONST_CONST_LABEL,
(void*)&&ZEND_FETCH_STATIC_PROP_R_SPEC_LABEL, (void*)&&ZEND_FETCH_STATIC_PROP_R_SPEC_LABEL,
(void*)&&ZEND_FETCH_STATIC_PROP_W_SPEC_LABEL, (void*)&&ZEND_FETCH_STATIC_PROP_W_SPEC_LABEL,
(void*)&&ZEND_FETCH_STATIC_PROP_RW_SPEC_LABEL, (void*)&&ZEND_FETCH_STATIC_PROP_RW_SPEC_LABEL,
@ -57705,6 +57648,10 @@ zend_leave_helper_SPEC_LABEL:
VM_TRACE(ZEND_DECLARE_CLASS_SPEC_CONST) VM_TRACE(ZEND_DECLARE_CLASS_SPEC_CONST)
ZEND_DECLARE_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); ZEND_DECLARE_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK(); HYBRID_BREAK();
HYBRID_CASE(ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST):
VM_TRACE(ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST)
ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
HYBRID_CASE(ZEND_YIELD_FROM_SPEC_CONST): HYBRID_CASE(ZEND_YIELD_FROM_SPEC_CONST):
VM_TRACE(ZEND_YIELD_FROM_SPEC_CONST) VM_TRACE(ZEND_YIELD_FROM_SPEC_CONST)
ZEND_YIELD_FROM_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); ZEND_YIELD_FROM_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@ -57929,18 +57876,6 @@ zend_leave_helper_SPEC_LABEL:
VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST) VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST)
ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK(); HYBRID_BREAK();
HYBRID_CASE(ZEND_DECLARE_INHERITED_CLASS_SPEC_CONST_CONST):
VM_TRACE(ZEND_DECLARE_INHERITED_CLASS_SPEC_CONST_CONST)
ZEND_DECLARE_INHERITED_CLASS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
HYBRID_CASE(ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_CONST_CONST):
VM_TRACE(ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_CONST_CONST)
ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
HYBRID_CASE(ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_CONST_CONST):
VM_TRACE(ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_CONST_CONST)
ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
HYBRID_CASE(ZEND_DECLARE_CONST_SPEC_CONST_CONST): HYBRID_CASE(ZEND_DECLARE_CONST_SPEC_CONST_CONST):
VM_TRACE(ZEND_DECLARE_CONST_SPEC_CONST_CONST) VM_TRACE(ZEND_DECLARE_CONST_SPEC_CONST_CONST)
ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@ -65401,7 +65336,6 @@ void zend_vm_init(void)
ZEND_INSTANCEOF_SPEC_CV_UNUSED_HANDLER, ZEND_INSTANCEOF_SPEC_CV_UNUSED_HANDLER,
ZEND_NULL_HANDLER, ZEND_NULL_HANDLER,
ZEND_DECLARE_CLASS_SPEC_CONST_HANDLER, ZEND_DECLARE_CLASS_SPEC_CONST_HANDLER,
ZEND_DECLARE_INHERITED_CLASS_SPEC_CONST_CONST_HANDLER,
ZEND_DECLARE_FUNCTION_SPEC_HANDLER, ZEND_DECLARE_FUNCTION_SPEC_HANDLER,
ZEND_YIELD_FROM_SPEC_CONST_HANDLER, ZEND_YIELD_FROM_SPEC_CONST_HANDLER,
ZEND_YIELD_FROM_SPEC_TMP_HANDLER, ZEND_YIELD_FROM_SPEC_TMP_HANDLER,
@ -65409,7 +65343,7 @@ void zend_vm_init(void)
ZEND_NULL_HANDLER, ZEND_NULL_HANDLER,
ZEND_YIELD_FROM_SPEC_CV_HANDLER, ZEND_YIELD_FROM_SPEC_CV_HANDLER,
ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER, ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER,
ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_CONST_CONST_HANDLER, ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER, ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER, ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER, ZEND_NULL_HANDLER,
@ -65764,7 +65698,6 @@ void zend_vm_init(void)
ZEND_NULL_HANDLER, ZEND_NULL_HANDLER,
ZEND_SPACESHIP_SPEC_CV_CV_HANDLER, ZEND_SPACESHIP_SPEC_CV_CV_HANDLER,
ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER,
ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_CONST_CONST_HANDLER,
ZEND_FETCH_STATIC_PROP_R_SPEC_HANDLER, ZEND_FETCH_STATIC_PROP_R_SPEC_HANDLER,
ZEND_FETCH_STATIC_PROP_W_SPEC_HANDLER, ZEND_FETCH_STATIC_PROP_W_SPEC_HANDLER,
ZEND_FETCH_STATIC_PROP_RW_SPEC_HANDLER, ZEND_FETCH_STATIC_PROP_RW_SPEC_HANDLER,
@ -67026,37 +66959,39 @@ void zend_vm_init(void)
2673, 2673,
2674 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2674 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
2699, 2699,
4180,
2700, 2700,
2701, 2701 | SPEC_RULE_OP1,
2702 | SPEC_RULE_OP1, 2706,
4180,
2707, 2707,
4182, 4180,
2708, 2708 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_OP_DATA,
4182, 2833 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
2709 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_OP_DATA, 2858,
2834 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
2859, 2859,
2860, 2860,
2861, 2861 | SPEC_RULE_OP1,
2862 | SPEC_RULE_OP1, 2866,
4180,
4180,
2867, 2867,
4182,
4182,
2868, 2868,
2869, 2869,
2870, 2870,
2871, 2871 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
2872 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2896 | SPEC_RULE_OP1,
2897 | SPEC_RULE_OP1, 2901,
2902, 2902,
2903, 2903,
2904, 2904,
2905, 2905 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
2906 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2930 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_DIM_OBJ,
2931 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_DIM_OBJ, 3030,
3031, 3031 | SPEC_RULE_OP1,
3032 | SPEC_RULE_OP1, 3036 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
3037 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3061,
4180,
3062, 3062,
3063, 3063,
3064, 3064,
@ -67065,37 +67000,35 @@ void zend_vm_init(void)
3067, 3067,
3068, 3068,
3069, 3069,
3070, 3070 | SPEC_RULE_OP1,
3071, 3075,
3072 | SPEC_RULE_OP1, 3076,
3077, 3077,
3078, 3078,
3079, 3079,
3080, 3080 | SPEC_RULE_OP1,
3081, 3085 | SPEC_RULE_OP1,
3082 | SPEC_RULE_OP1, 3090 | SPEC_RULE_OP1,
3087 | SPEC_RULE_OP1, 3095 | SPEC_RULE_OP1,
3092 | SPEC_RULE_OP1, 3100 | SPEC_RULE_OP1,
3097 | SPEC_RULE_OP1, 3105,
3102 | SPEC_RULE_OP1, 3106 | SPEC_RULE_OP1,
3107, 3111,
3108 | SPEC_RULE_OP1, 3112 | SPEC_RULE_OP1,
3113, 3117,
3114 | SPEC_RULE_OP1, 3118 | SPEC_RULE_ISSET,
3119, 3120 | SPEC_RULE_OP2,
3120 | SPEC_RULE_ISSET, 3125 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
3122 | SPEC_RULE_OP2, 3150 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_OP_DATA,
3127 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3275 | SPEC_RULE_OP_DATA,
3152 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_OP_DATA, 3280,
3277 | SPEC_RULE_OP_DATA, 3281,
3282, 3282,
3283, 3283,
3284, 3284,
3285, 3285,
3286, 3286,
3287, 4180
3288,
4182
}; };
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
zend_opcode_handler_funcs = labels; zend_opcode_handler_funcs = labels;
@ -67302,7 +67235,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) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3290 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; spec = 3288 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
if (op->op1_type < op->op2_type) { if (op->op1_type < op->op2_type) {
zend_swap_operands(op); zend_swap_operands(op);
} }
@ -67310,7 +67243,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) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3315 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; spec = 3313 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
if (op->op1_type < op->op2_type) { if (op->op1_type < op->op2_type) {
zend_swap_operands(op); zend_swap_operands(op);
} }
@ -67318,7 +67251,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) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3340 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; spec = 3338 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
if (op->op1_type < op->op2_type) { if (op->op1_type < op->op2_type) {
zend_swap_operands(op); zend_swap_operands(op);
} }
@ -67329,17 +67262,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) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3365 | SPEC_RULE_OP1 | SPEC_RULE_OP2; spec = 3363 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
} else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3390 | SPEC_RULE_OP1 | SPEC_RULE_OP2; spec = 3388 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3415 | SPEC_RULE_OP1 | SPEC_RULE_OP2; spec = 3413 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
} }
break; break;
case ZEND_MUL: case ZEND_MUL:
@ -67350,17 +67283,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) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3440 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; spec = 3438 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
} else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3465 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; spec = 3463 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3490 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; spec = 3488 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
} }
break; break;
case ZEND_IS_EQUAL: case ZEND_IS_EQUAL:
@ -67371,12 +67304,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) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3515 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; spec = 3513 | 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) { } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3590 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; spec = 3588 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
} }
break; break;
case ZEND_IS_NOT_EQUAL: case ZEND_IS_NOT_EQUAL:
@ -67387,12 +67320,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) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3665 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; spec = 3663 | 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) { } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3740 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; spec = 3738 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
} }
break; break;
case ZEND_IS_SMALLER: case ZEND_IS_SMALLER:
@ -67400,12 +67333,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) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3815 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; spec = 3813 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3890 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; spec = 3888 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
} }
break; break;
case ZEND_IS_SMALLER_OR_EQUAL: case ZEND_IS_SMALLER_OR_EQUAL:
@ -67413,75 +67346,75 @@ 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) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 3965 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; spec = 3963 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 4040 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; spec = 4038 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
} }
break; break;
case ZEND_QM_ASSIGN: case ZEND_QM_ASSIGN:
if (op1_info == MAY_BE_DOUBLE) { if (op1_info == MAY_BE_DOUBLE) {
spec = 4133 | SPEC_RULE_OP1; spec = 4131 | 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 ((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 = 4138 | SPEC_RULE_OP1; spec = 4136 | SPEC_RULE_OP1;
} }
break; break;
case ZEND_PRE_INC: case ZEND_PRE_INC:
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
spec = 4115 | SPEC_RULE_RETVAL; spec = 4113 | SPEC_RULE_RETVAL;
} else if (op1_info == MAY_BE_LONG) { } else if (op1_info == MAY_BE_LONG) {
spec = 4117 | SPEC_RULE_RETVAL; spec = 4115 | SPEC_RULE_RETVAL;
} else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) {
spec = 4119 | SPEC_RULE_RETVAL; spec = 4117 | SPEC_RULE_RETVAL;
} }
break; break;
case ZEND_PRE_DEC: case ZEND_PRE_DEC:
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
spec = 4121 | SPEC_RULE_RETVAL; spec = 4119 | SPEC_RULE_RETVAL;
} else if (op1_info == MAY_BE_LONG) { } else if (op1_info == MAY_BE_LONG) {
spec = 4123 | SPEC_RULE_RETVAL; spec = 4121 | SPEC_RULE_RETVAL;
} else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) {
spec = 4125 | SPEC_RULE_RETVAL; spec = 4123 | SPEC_RULE_RETVAL;
} }
break; break;
case ZEND_POST_INC: case ZEND_POST_INC:
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
spec = 4127; spec = 4125;
} else if (op1_info == MAY_BE_LONG) { } else if (op1_info == MAY_BE_LONG) {
spec = 4128; spec = 4126;
} else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) {
spec = 4129; spec = 4127;
} }
break; break;
case ZEND_POST_DEC: case ZEND_POST_DEC:
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
spec = 4130; spec = 4128;
} else if (op1_info == MAY_BE_LONG) { } else if (op1_info == MAY_BE_LONG) {
spec = 4131; spec = 4129;
} else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) {
spec = 4132; spec = 4130;
} }
break; break;
case ZEND_JMP: case ZEND_JMP:
if (OP_JMP_ADDR(op, op->op1) > op) { if (OP_JMP_ADDR(op, op->op1) > op) {
spec = 3289; spec = 3287;
} }
break; break;
case ZEND_SEND_VAL: case ZEND_SEND_VAL:
if (op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { if (op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) {
spec = 4178; spec = 4176;
} }
break; break;
case ZEND_SEND_VAR_EX: case ZEND_SEND_VAR_EX:
if (op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { if (op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
spec = 4173 | SPEC_RULE_OP1; spec = 4171 | SPEC_RULE_OP1;
} }
break; break;
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
if (op->op2_type == IS_CV && (op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) { if (op->op2_type == IS_CV && (op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) {
spec = 4180 | SPEC_RULE_RETVAL; spec = 4178 | SPEC_RULE_RETVAL;
} }
break; break;
case ZEND_FETCH_DIM_R: case ZEND_FETCH_DIM_R:
@ -67489,17 +67422,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) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break; break;
} }
spec = 4143 | SPEC_RULE_OP1 | SPEC_RULE_OP2; spec = 4141 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
} }
break; break;
case ZEND_SEND_VAL_EX: case ZEND_SEND_VAL_EX:
if (op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { if (op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) {
spec = 4179; spec = 4177;
} }
break; break;
case ZEND_SEND_VAR: case ZEND_SEND_VAR:
if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
spec = 4168 | SPEC_RULE_OP1; spec = 4166 | SPEC_RULE_OP1;
} }
break; break;
case ZEND_BW_OR: case ZEND_BW_OR:

File diff suppressed because it is too large Load diff

View file

@ -163,12 +163,12 @@ static const char *zend_vm_opcodes_names[209] = {
"ZEND_OP_DATA", "ZEND_OP_DATA",
"ZEND_INSTANCEOF", "ZEND_INSTANCEOF",
"ZEND_DECLARE_CLASS", "ZEND_DECLARE_CLASS",
"ZEND_DECLARE_INHERITED_CLASS", NULL,
"ZEND_DECLARE_FUNCTION", "ZEND_DECLARE_FUNCTION",
"ZEND_YIELD_FROM", "ZEND_YIELD_FROM",
"ZEND_DECLARE_CONST", "ZEND_DECLARE_CONST",
NULL, NULL,
"ZEND_DECLARE_INHERITED_CLASS_DELAYED", "ZEND_DECLARE_CLASS_DELAYED",
NULL, NULL,
"ZEND_ASSIGN_DIM", "ZEND_ASSIGN_DIM",
"ZEND_ISSET_ISEMPTY_PROP_OBJ", "ZEND_ISSET_ISEMPTY_PROP_OBJ",
@ -195,7 +195,7 @@ static const char *zend_vm_opcodes_names[209] = {
"ZEND_COALESCE", "ZEND_COALESCE",
"ZEND_SPACESHIP", "ZEND_SPACESHIP",
"ZEND_DECLARE_ANON_CLASS", "ZEND_DECLARE_ANON_CLASS",
"ZEND_DECLARE_ANON_INHERITED_CLASS", NULL,
"ZEND_FETCH_STATIC_PROP_R", "ZEND_FETCH_STATIC_PROP_R",
"ZEND_FETCH_STATIC_PROP_W", "ZEND_FETCH_STATIC_PROP_W",
"ZEND_FETCH_STATIC_PROP_RW", "ZEND_FETCH_STATIC_PROP_RW",
@ -375,12 +375,12 @@ static uint32_t zend_vm_opcodes_flags[209] = {
0x00000000, 0x00000000,
0x00047305, 0x00047305,
0x00000003, 0x00000003,
0x00000303, 0x00000000,
0x00000000, 0x00000000,
0x00000003, 0x00000003,
0x00000303, 0x00000303,
0x00000000, 0x00000000,
0x00000303, 0x00000003,
0x00000000, 0x00000000,
0x00006701, 0x00006701,
0x00060757, 0x00060757,
@ -407,7 +407,7 @@ static uint32_t zend_vm_opcodes_flags[209] = {
0x00002007, 0x00002007,
0x00000707, 0x00000707,
0x03000000, 0x03000000,
0x03000303, 0x00000000,
0x00047000, 0x00047000,
0x00647000, 0x00647000,
0x00047000, 0x00047000,

View file

@ -76,212 +76,210 @@ ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(zend_uchar opcode);
END_EXTERN_C() END_EXTERN_C()
#define ZEND_NOP 0 #define ZEND_NOP 0
#define ZEND_ADD 1 #define ZEND_ADD 1
#define ZEND_SUB 2 #define ZEND_SUB 2
#define ZEND_MUL 3 #define ZEND_MUL 3
#define ZEND_DIV 4 #define ZEND_DIV 4
#define ZEND_MOD 5 #define ZEND_MOD 5
#define ZEND_SL 6 #define ZEND_SL 6
#define ZEND_SR 7 #define ZEND_SR 7
#define ZEND_CONCAT 8 #define ZEND_CONCAT 8
#define ZEND_BW_OR 9 #define ZEND_BW_OR 9
#define ZEND_BW_AND 10 #define ZEND_BW_AND 10
#define ZEND_BW_XOR 11 #define ZEND_BW_XOR 11
#define ZEND_BW_NOT 12 #define ZEND_BW_NOT 12
#define ZEND_BOOL_NOT 13 #define ZEND_BOOL_NOT 13
#define ZEND_BOOL_XOR 14 #define ZEND_BOOL_XOR 14
#define ZEND_IS_IDENTICAL 15 #define ZEND_IS_IDENTICAL 15
#define ZEND_IS_NOT_IDENTICAL 16 #define ZEND_IS_NOT_IDENTICAL 16
#define ZEND_IS_EQUAL 17 #define ZEND_IS_EQUAL 17
#define ZEND_IS_NOT_EQUAL 18 #define ZEND_IS_NOT_EQUAL 18
#define ZEND_IS_SMALLER 19 #define ZEND_IS_SMALLER 19
#define ZEND_IS_SMALLER_OR_EQUAL 20 #define ZEND_IS_SMALLER_OR_EQUAL 20
#define ZEND_CAST 21 #define ZEND_CAST 21
#define ZEND_QM_ASSIGN 22 #define ZEND_QM_ASSIGN 22
#define ZEND_ASSIGN_ADD 23 #define ZEND_ASSIGN_ADD 23
#define ZEND_ASSIGN_SUB 24 #define ZEND_ASSIGN_SUB 24
#define ZEND_ASSIGN_MUL 25 #define ZEND_ASSIGN_MUL 25
#define ZEND_ASSIGN_DIV 26 #define ZEND_ASSIGN_DIV 26
#define ZEND_ASSIGN_MOD 27 #define ZEND_ASSIGN_MOD 27
#define ZEND_ASSIGN_SL 28 #define ZEND_ASSIGN_SL 28
#define ZEND_ASSIGN_SR 29 #define ZEND_ASSIGN_SR 29
#define ZEND_ASSIGN_CONCAT 30 #define ZEND_ASSIGN_CONCAT 30
#define ZEND_ASSIGN_BW_OR 31 #define ZEND_ASSIGN_BW_OR 31
#define ZEND_ASSIGN_BW_AND 32 #define ZEND_ASSIGN_BW_AND 32
#define ZEND_ASSIGN_BW_XOR 33 #define ZEND_ASSIGN_BW_XOR 33
#define ZEND_PRE_INC 34 #define ZEND_PRE_INC 34
#define ZEND_PRE_DEC 35 #define ZEND_PRE_DEC 35
#define ZEND_POST_INC 36 #define ZEND_POST_INC 36
#define ZEND_POST_DEC 37 #define ZEND_POST_DEC 37
#define ZEND_ASSIGN 38 #define ZEND_ASSIGN 38
#define ZEND_ASSIGN_REF 39 #define ZEND_ASSIGN_REF 39
#define ZEND_ECHO 40 #define ZEND_ECHO 40
#define ZEND_GENERATOR_CREATE 41 #define ZEND_GENERATOR_CREATE 41
#define ZEND_JMP 42 #define ZEND_JMP 42
#define ZEND_JMPZ 43 #define ZEND_JMPZ 43
#define ZEND_JMPNZ 44 #define ZEND_JMPNZ 44
#define ZEND_JMPZNZ 45 #define ZEND_JMPZNZ 45
#define ZEND_JMPZ_EX 46 #define ZEND_JMPZ_EX 46
#define ZEND_JMPNZ_EX 47 #define ZEND_JMPNZ_EX 47
#define ZEND_CASE 48 #define ZEND_CASE 48
#define ZEND_CHECK_VAR 49 #define ZEND_CHECK_VAR 49
#define ZEND_SEND_VAR_NO_REF_EX 50 #define ZEND_SEND_VAR_NO_REF_EX 50
#define ZEND_MAKE_REF 51 #define ZEND_MAKE_REF 51
#define ZEND_BOOL 52 #define ZEND_BOOL 52
#define ZEND_FAST_CONCAT 53 #define ZEND_FAST_CONCAT 53
#define ZEND_ROPE_INIT 54 #define ZEND_ROPE_INIT 54
#define ZEND_ROPE_ADD 55 #define ZEND_ROPE_ADD 55
#define ZEND_ROPE_END 56 #define ZEND_ROPE_END 56
#define ZEND_BEGIN_SILENCE 57 #define ZEND_BEGIN_SILENCE 57
#define ZEND_END_SILENCE 58 #define ZEND_END_SILENCE 58
#define ZEND_INIT_FCALL_BY_NAME 59 #define ZEND_INIT_FCALL_BY_NAME 59
#define ZEND_DO_FCALL 60 #define ZEND_DO_FCALL 60
#define ZEND_INIT_FCALL 61 #define ZEND_INIT_FCALL 61
#define ZEND_RETURN 62 #define ZEND_RETURN 62
#define ZEND_RECV 63 #define ZEND_RECV 63
#define ZEND_RECV_INIT 64 #define ZEND_RECV_INIT 64
#define ZEND_SEND_VAL 65 #define ZEND_SEND_VAL 65
#define ZEND_SEND_VAR_EX 66 #define ZEND_SEND_VAR_EX 66
#define ZEND_SEND_REF 67 #define ZEND_SEND_REF 67
#define ZEND_NEW 68 #define ZEND_NEW 68
#define ZEND_INIT_NS_FCALL_BY_NAME 69 #define ZEND_INIT_NS_FCALL_BY_NAME 69
#define ZEND_FREE 70 #define ZEND_FREE 70
#define ZEND_INIT_ARRAY 71 #define ZEND_INIT_ARRAY 71
#define ZEND_ADD_ARRAY_ELEMENT 72 #define ZEND_ADD_ARRAY_ELEMENT 72
#define ZEND_INCLUDE_OR_EVAL 73 #define ZEND_INCLUDE_OR_EVAL 73
#define ZEND_UNSET_VAR 74 #define ZEND_UNSET_VAR 74
#define ZEND_UNSET_DIM 75 #define ZEND_UNSET_DIM 75
#define ZEND_UNSET_OBJ 76 #define ZEND_UNSET_OBJ 76
#define ZEND_FE_RESET_R 77 #define ZEND_FE_RESET_R 77
#define ZEND_FE_FETCH_R 78 #define ZEND_FE_FETCH_R 78
#define ZEND_EXIT 79 #define ZEND_EXIT 79
#define ZEND_FETCH_R 80 #define ZEND_FETCH_R 80
#define ZEND_FETCH_DIM_R 81 #define ZEND_FETCH_DIM_R 81
#define ZEND_FETCH_OBJ_R 82 #define ZEND_FETCH_OBJ_R 82
#define ZEND_FETCH_W 83 #define ZEND_FETCH_W 83
#define ZEND_FETCH_DIM_W 84 #define ZEND_FETCH_DIM_W 84
#define ZEND_FETCH_OBJ_W 85 #define ZEND_FETCH_OBJ_W 85
#define ZEND_FETCH_RW 86 #define ZEND_FETCH_RW 86
#define ZEND_FETCH_DIM_RW 87 #define ZEND_FETCH_DIM_RW 87
#define ZEND_FETCH_OBJ_RW 88 #define ZEND_FETCH_OBJ_RW 88
#define ZEND_FETCH_IS 89 #define ZEND_FETCH_IS 89
#define ZEND_FETCH_DIM_IS 90 #define ZEND_FETCH_DIM_IS 90
#define ZEND_FETCH_OBJ_IS 91 #define ZEND_FETCH_OBJ_IS 91
#define ZEND_FETCH_FUNC_ARG 92 #define ZEND_FETCH_FUNC_ARG 92
#define ZEND_FETCH_DIM_FUNC_ARG 93 #define ZEND_FETCH_DIM_FUNC_ARG 93
#define ZEND_FETCH_OBJ_FUNC_ARG 94 #define ZEND_FETCH_OBJ_FUNC_ARG 94
#define ZEND_FETCH_UNSET 95 #define ZEND_FETCH_UNSET 95
#define ZEND_FETCH_DIM_UNSET 96 #define ZEND_FETCH_DIM_UNSET 96
#define ZEND_FETCH_OBJ_UNSET 97 #define ZEND_FETCH_OBJ_UNSET 97
#define ZEND_FETCH_LIST_R 98 #define ZEND_FETCH_LIST_R 98
#define ZEND_FETCH_CONSTANT 99 #define ZEND_FETCH_CONSTANT 99
#define ZEND_CHECK_FUNC_ARG 100 #define ZEND_CHECK_FUNC_ARG 100
#define ZEND_EXT_STMT 101 #define ZEND_EXT_STMT 101
#define ZEND_EXT_FCALL_BEGIN 102 #define ZEND_EXT_FCALL_BEGIN 102
#define ZEND_EXT_FCALL_END 103 #define ZEND_EXT_FCALL_END 103
#define ZEND_EXT_NOP 104 #define ZEND_EXT_NOP 104
#define ZEND_TICKS 105 #define ZEND_TICKS 105
#define ZEND_SEND_VAR_NO_REF 106 #define ZEND_SEND_VAR_NO_REF 106
#define ZEND_CATCH 107 #define ZEND_CATCH 107
#define ZEND_THROW 108 #define ZEND_THROW 108
#define ZEND_FETCH_CLASS 109 #define ZEND_FETCH_CLASS 109
#define ZEND_CLONE 110 #define ZEND_CLONE 110
#define ZEND_RETURN_BY_REF 111 #define ZEND_RETURN_BY_REF 111
#define ZEND_INIT_METHOD_CALL 112 #define ZEND_INIT_METHOD_CALL 112
#define ZEND_INIT_STATIC_METHOD_CALL 113 #define ZEND_INIT_STATIC_METHOD_CALL 113
#define ZEND_ISSET_ISEMPTY_VAR 114 #define ZEND_ISSET_ISEMPTY_VAR 114
#define ZEND_ISSET_ISEMPTY_DIM_OBJ 115 #define ZEND_ISSET_ISEMPTY_DIM_OBJ 115
#define ZEND_SEND_VAL_EX 116 #define ZEND_SEND_VAL_EX 116
#define ZEND_SEND_VAR 117 #define ZEND_SEND_VAR 117
#define ZEND_INIT_USER_CALL 118 #define ZEND_INIT_USER_CALL 118
#define ZEND_SEND_ARRAY 119 #define ZEND_SEND_ARRAY 119
#define ZEND_SEND_USER 120 #define ZEND_SEND_USER 120
#define ZEND_STRLEN 121 #define ZEND_STRLEN 121
#define ZEND_DEFINED 122 #define ZEND_DEFINED 122
#define ZEND_TYPE_CHECK 123 #define ZEND_TYPE_CHECK 123
#define ZEND_VERIFY_RETURN_TYPE 124 #define ZEND_VERIFY_RETURN_TYPE 124
#define ZEND_FE_RESET_RW 125 #define ZEND_FE_RESET_RW 125
#define ZEND_FE_FETCH_RW 126 #define ZEND_FE_FETCH_RW 126
#define ZEND_FE_FREE 127 #define ZEND_FE_FREE 127
#define ZEND_INIT_DYNAMIC_CALL 128 #define ZEND_INIT_DYNAMIC_CALL 128
#define ZEND_DO_ICALL 129 #define ZEND_DO_ICALL 129
#define ZEND_DO_UCALL 130 #define ZEND_DO_UCALL 130
#define ZEND_DO_FCALL_BY_NAME 131 #define ZEND_DO_FCALL_BY_NAME 131
#define ZEND_PRE_INC_OBJ 132 #define ZEND_PRE_INC_OBJ 132
#define ZEND_PRE_DEC_OBJ 133 #define ZEND_PRE_DEC_OBJ 133
#define ZEND_POST_INC_OBJ 134 #define ZEND_POST_INC_OBJ 134
#define ZEND_POST_DEC_OBJ 135 #define ZEND_POST_DEC_OBJ 135
#define ZEND_ASSIGN_OBJ 136 #define ZEND_ASSIGN_OBJ 136
#define ZEND_OP_DATA 137 #define ZEND_OP_DATA 137
#define ZEND_INSTANCEOF 138 #define ZEND_INSTANCEOF 138
#define ZEND_DECLARE_CLASS 139 #define ZEND_DECLARE_CLASS 139
#define ZEND_DECLARE_INHERITED_CLASS 140 #define ZEND_DECLARE_FUNCTION 141
#define ZEND_DECLARE_FUNCTION 141 #define ZEND_YIELD_FROM 142
#define ZEND_YIELD_FROM 142 #define ZEND_DECLARE_CONST 143
#define ZEND_DECLARE_CONST 143 #define ZEND_DECLARE_CLASS_DELAYED 145
#define ZEND_DECLARE_INHERITED_CLASS_DELAYED 145 #define ZEND_ASSIGN_DIM 147
#define ZEND_ASSIGN_DIM 147 #define ZEND_ISSET_ISEMPTY_PROP_OBJ 148
#define ZEND_ISSET_ISEMPTY_PROP_OBJ 148 #define ZEND_HANDLE_EXCEPTION 149
#define ZEND_HANDLE_EXCEPTION 149 #define ZEND_USER_OPCODE 150
#define ZEND_USER_OPCODE 150 #define ZEND_ASSERT_CHECK 151
#define ZEND_ASSERT_CHECK 151 #define ZEND_JMP_SET 152
#define ZEND_JMP_SET 152 #define ZEND_DECLARE_LAMBDA_FUNCTION 153
#define ZEND_DECLARE_LAMBDA_FUNCTION 153 #define ZEND_SEPARATE 156
#define ZEND_SEPARATE 156 #define ZEND_FETCH_CLASS_NAME 157
#define ZEND_FETCH_CLASS_NAME 157 #define ZEND_CALL_TRAMPOLINE 158
#define ZEND_CALL_TRAMPOLINE 158 #define ZEND_DISCARD_EXCEPTION 159
#define ZEND_DISCARD_EXCEPTION 159 #define ZEND_YIELD 160
#define ZEND_YIELD 160 #define ZEND_GENERATOR_RETURN 161
#define ZEND_GENERATOR_RETURN 161 #define ZEND_FAST_CALL 162
#define ZEND_FAST_CALL 162 #define ZEND_FAST_RET 163
#define ZEND_FAST_RET 163 #define ZEND_RECV_VARIADIC 164
#define ZEND_RECV_VARIADIC 164 #define ZEND_SEND_UNPACK 165
#define ZEND_SEND_UNPACK 165 #define ZEND_POW 166
#define ZEND_POW 166 #define ZEND_ASSIGN_POW 167
#define ZEND_ASSIGN_POW 167 #define ZEND_BIND_GLOBAL 168
#define ZEND_BIND_GLOBAL 168 #define ZEND_COALESCE 169
#define ZEND_COALESCE 169 #define ZEND_SPACESHIP 170
#define ZEND_SPACESHIP 170 #define ZEND_DECLARE_ANON_CLASS 171
#define ZEND_DECLARE_ANON_CLASS 171 #define ZEND_FETCH_STATIC_PROP_R 173
#define ZEND_DECLARE_ANON_INHERITED_CLASS 172 #define ZEND_FETCH_STATIC_PROP_W 174
#define ZEND_FETCH_STATIC_PROP_R 173 #define ZEND_FETCH_STATIC_PROP_RW 175
#define ZEND_FETCH_STATIC_PROP_W 174 #define ZEND_FETCH_STATIC_PROP_IS 176
#define ZEND_FETCH_STATIC_PROP_RW 175 #define ZEND_FETCH_STATIC_PROP_FUNC_ARG 177
#define ZEND_FETCH_STATIC_PROP_IS 176 #define ZEND_FETCH_STATIC_PROP_UNSET 178
#define ZEND_FETCH_STATIC_PROP_FUNC_ARG 177 #define ZEND_UNSET_STATIC_PROP 179
#define ZEND_FETCH_STATIC_PROP_UNSET 178 #define ZEND_ISSET_ISEMPTY_STATIC_PROP 180
#define ZEND_UNSET_STATIC_PROP 179 #define ZEND_FETCH_CLASS_CONSTANT 181
#define ZEND_ISSET_ISEMPTY_STATIC_PROP 180 #define ZEND_BIND_LEXICAL 182
#define ZEND_FETCH_CLASS_CONSTANT 181 #define ZEND_BIND_STATIC 183
#define ZEND_BIND_LEXICAL 182 #define ZEND_FETCH_THIS 184
#define ZEND_BIND_STATIC 183 #define ZEND_SEND_FUNC_ARG 185
#define ZEND_FETCH_THIS 184 #define ZEND_ISSET_ISEMPTY_THIS 186
#define ZEND_SEND_FUNC_ARG 185 #define ZEND_SWITCH_LONG 187
#define ZEND_ISSET_ISEMPTY_THIS 186 #define ZEND_SWITCH_STRING 188
#define ZEND_SWITCH_LONG 187 #define ZEND_IN_ARRAY 189
#define ZEND_SWITCH_STRING 188 #define ZEND_COUNT 190
#define ZEND_IN_ARRAY 189 #define ZEND_GET_CLASS 191
#define ZEND_COUNT 190 #define ZEND_GET_CALLED_CLASS 192
#define ZEND_GET_CLASS 191 #define ZEND_GET_TYPE 193
#define ZEND_GET_CALLED_CLASS 192 #define ZEND_FUNC_NUM_ARGS 194
#define ZEND_GET_TYPE 193 #define ZEND_FUNC_GET_ARGS 195
#define ZEND_FUNC_NUM_ARGS 194 #define ZEND_UNSET_CV 196
#define ZEND_FUNC_GET_ARGS 195 #define ZEND_ISSET_ISEMPTY_CV 197
#define ZEND_UNSET_CV 196 #define ZEND_FETCH_LIST_W 198
#define ZEND_ISSET_ISEMPTY_CV 197 #define ZEND_ARRAY_KEY_EXISTS 199
#define ZEND_FETCH_LIST_W 198 #define ZEND_ASSIGN_OBJ_REF 200
#define ZEND_ARRAY_KEY_EXISTS 199 #define ZEND_ASSIGN_STATIC_PROP 201
#define ZEND_ASSIGN_OBJ_REF 200 #define ZEND_ASSIGN_STATIC_PROP_REF 202
#define ZEND_ASSIGN_STATIC_PROP 201 #define ZEND_PRE_INC_STATIC_PROP 203
#define ZEND_ASSIGN_STATIC_PROP_REF 202 #define ZEND_PRE_DEC_STATIC_PROP 204
#define ZEND_PRE_INC_STATIC_PROP 203 #define ZEND_POST_INC_STATIC_PROP 205
#define ZEND_PRE_DEC_STATIC_PROP 204 #define ZEND_POST_DEC_STATIC_PROP 206
#define ZEND_POST_INC_STATIC_PROP 205 #define ZEND_COPY_TMP 207
#define ZEND_POST_DEC_STATIC_PROP 206 #define ZEND_ADD_ARRAY_UNPACK 208
#define ZEND_COPY_TMP 207
#define ZEND_ADD_ARRAY_UNPACK 208
#define ZEND_VM_LAST_OPCODE 208 #define ZEND_VM_LAST_OPCODE 208
#endif #endif

View file

@ -990,7 +990,6 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
} }
break; break;
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline, new_opcodes + blocks[b->successors[0]].start); opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline, new_opcodes + blocks[b->successors[0]].start);

View file

@ -271,17 +271,9 @@ literals_handle_static_prop:
break; break;
case ZEND_DECLARE_FUNCTION: case ZEND_DECLARE_FUNCTION:
case ZEND_DECLARE_CLASS: case ZEND_DECLARE_CLASS:
case ZEND_DECLARE_CLASS_DELAYED:
LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 2); LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 2);
break; break;
case ZEND_DECLARE_INHERITED_CLASS:
case ZEND_DECLARE_INHERITED_CLASS_DELAYED:
LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 2);
LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 2);
break;
case ZEND_DECLARE_ANON_INHERITED_CLASS:
LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1);
LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 2);
break;
case ZEND_ISSET_ISEMPTY_DIM_OBJ: case ZEND_ISSET_ISEMPTY_DIM_OBJ:
case ZEND_ASSIGN_DIM: case ZEND_ASSIGN_DIM:
case ZEND_UNSET_DIM: case ZEND_UNSET_DIM:

View file

@ -608,7 +608,6 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa
} }
break; break;
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
if (ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value) == old->start) { if (ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value) == old->start) {

View file

@ -287,9 +287,7 @@ static zend_bool can_replace_op2(
const zend_op_array *op_array, zend_op *opline, zend_ssa_op *ssa_op) { const zend_op_array *op_array, zend_op *opline, zend_ssa_op *ssa_op) {
switch (opline->opcode) { switch (opline->opcode) {
/* Do not accept CONST */ /* Do not accept CONST */
case ZEND_DECLARE_INHERITED_CLASS: case ZEND_DECLARE_CLASS_DELAYED:
case ZEND_DECLARE_INHERITED_CLASS_DELAYED:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_BIND_LEXICAL: case ZEND_BIND_LEXICAL:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
@ -1948,7 +1946,6 @@ static void sccp_mark_feasible_successors(
case ZEND_ASSERT_CHECK: case ZEND_ASSERT_CHECK:
case ZEND_CATCH: case ZEND_CATCH:
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
scdf_mark_edge_feasible(scdf, block_num, block->successors[0]); scdf_mark_edge_feasible(scdf, block_num, block->successors[0]);

View file

@ -376,7 +376,6 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
BB_START(i + 1); BB_START(i + 1);
break; break;
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
BB_START(ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)); BB_START(ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
@ -537,7 +536,6 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
} }
break; break;
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
block->successors_count = 2; block->successors_count = 2;

View file

@ -3164,7 +3164,6 @@ static int zend_update_type_info(const zend_op_array *op_array,
break; break;
} }
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
UPDATE_SSA_TYPE(MAY_BE_CLASS, ssa_ops[i].result_def); UPDATE_SSA_TYPE(MAY_BE_CLASS, ssa_ops[i].result_def);
if (script && (ce = zend_hash_find_ptr(&script->class_table, Z_STR_P(CRT_CONSTANT_EX(op_array, opline, opline->op1, ssa->rt_constants)))) != NULL) { if (script && (ce = zend_hash_find_ptr(&script->class_table, Z_STR_P(CRT_CONSTANT_EX(op_array, opline, opline->op1, ssa->rt_constants)))) != NULL) {
UPDATE_SSA_OBJ_TYPE(ce, 0, ssa_ops[i].result_def); UPDATE_SSA_OBJ_TYPE(ce, 0, ssa_ops[i].result_def);

View file

@ -773,7 +773,6 @@ void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, z
ZEND_SET_OP_JMP_ADDR(new_opline, new_opline->op2, ZEND_OP2_JMP_ADDR(opline)); ZEND_SET_OP_JMP_ADDR(new_opline, new_opline->op2, ZEND_OP2_JMP_ADDR(opline));
break; break;
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
new_opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, new_opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)); new_opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, new_opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
@ -824,7 +823,6 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_
} }
break; break;
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value) - shiftlist[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)]); opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value) - shiftlist[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)]);
@ -1206,7 +1204,6 @@ static void zend_redo_pass_two(zend_op_array *op_array)
} }
break; break;
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
case ZEND_SWITCH_LONG: case ZEND_SWITCH_LONG:
@ -1295,7 +1292,6 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa)
} }
break; break;
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
case ZEND_SWITCH_LONG: case ZEND_SWITCH_LONG:

View file

@ -3623,7 +3623,7 @@ static void preload_link(void)
} else { } else {
CG(zend_lineno) = ce->info.user.line_start; CG(zend_lineno) = ce->info.user.line_start;
} }
zend_do_link_class(ce, parent); zend_do_link_class(ce);
CG(in_compilation) = 0; CG(in_compilation) = 0;
CG(compiled_filename) = NULL; CG(compiled_filename) = NULL;
@ -3726,8 +3726,7 @@ static void preload_link(void)
while (opline != end) { while (opline != end) {
switch (opline->opcode) { switch (opline->opcode) {
case ZEND_DECLARE_CLASS: case ZEND_DECLARE_CLASS:
case ZEND_DECLARE_INHERITED_CLASS: case ZEND_DECLARE_CLASS_DELAYED:
case ZEND_DECLARE_INHERITED_CLASS_DELAYED:
key = Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1); key = Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1);
if (!zend_hash_exists(&script->script.class_table, key)) { if (!zend_hash_exists(&script->script.class_table, key)) {
MAKE_NOP(opline); MAKE_NOP(opline);

View file

@ -2510,7 +2510,6 @@ static int zend_jit(zend_op_array *op_array, zend_ssa *ssa, const zend_op *rt_op
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
if (!zend_jit_handler(&dasm_state, opline, zend_may_throw(opline, op_array, ssa)) || if (!zend_jit_handler(&dasm_state, opline, zend_may_throw(opline, op_array, ssa)) ||
!zend_jit_cond_jmp(&dasm_state, opline + 1, ssa->cfg.blocks[b].successors[0])) { !zend_jit_cond_jmp(&dasm_state, opline + 1, ssa->cfg.blocks[b].successors[0])) {
goto jit_failure; goto jit_failure;

View file

@ -7156,7 +7156,6 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, zend
case ZEND_ASSERT_CHECK: case ZEND_ASSERT_CHECK:
case ZEND_CATCH: case ZEND_CATCH:
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
return 1; return 1;

View file

@ -467,7 +467,6 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra
} }
break; break;
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
case ZEND_SWITCH_LONG: case ZEND_SWITCH_LONG:
@ -1185,7 +1184,6 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
} }
break; break;
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
case ZEND_SWITCH_LONG: case ZEND_SWITCH_LONG:

View file

@ -454,7 +454,6 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
} }
break; break;
case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_CLASS:
case ZEND_DECLARE_ANON_INHERITED_CLASS:
case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW: case ZEND_FE_FETCH_RW:
case ZEND_SWITCH_LONG: case ZEND_SWITCH_LONG:

View file

@ -68,15 +68,4 @@ foreach (new \RecursiveIteratorIterator (new fooIterator ($foo)) as $bar) ;
?> ?>
--EXPECTF-- --EXPECTF--
Fatal error: Uncaught Error: Class 'NotExists' not found in %sbug73423.php(%d) : eval()'d code:1 Fatal error: Class 'NotExists' not found in %s(%d) : eval()'d code on line 1
Stack trace:
#0 %sbug73423.php(%d): eval()
#1 %sbug73423.php(%d): fooIterator->__destruct()
#2 {main}
Next Error: Class 'NotExists' not found in %sbug73423.php(%d) : eval()'d code:1
Stack trace:
#0 %sbug73423.php(%d): eval()
#1 %sbug73423.php(%d): fooIterator->__destruct()
#2 {main}
thrown in %sbug73423.php(%d) : eval()'d code on line 1

View file

@ -480,9 +480,9 @@ static PHP_FUNCTION(phpdbg_start_oplog)
static zend_always_inline zend_bool phpdbg_is_ignored_opcode(zend_uchar opcode) { static zend_always_inline zend_bool phpdbg_is_ignored_opcode(zend_uchar opcode) {
return return
opcode == ZEND_NOP || opcode == ZEND_OP_DATA || opcode == ZEND_FE_FREE || opcode == ZEND_FREE || opcode == ZEND_ASSERT_CHECK || opcode == ZEND_VERIFY_RETURN_TYPE opcode == ZEND_NOP || opcode == ZEND_OP_DATA || opcode == ZEND_FE_FREE || opcode == ZEND_FREE || opcode == ZEND_ASSERT_CHECK || opcode == ZEND_VERIFY_RETURN_TYPE
|| opcode == ZEND_DECLARE_CONST || opcode == ZEND_DECLARE_CLASS || opcode == ZEND_DECLARE_INHERITED_CLASS || opcode == ZEND_DECLARE_FUNCTION || opcode == ZEND_DECLARE_CONST || opcode == ZEND_DECLARE_CLASS || opcode == ZEND_DECLARE_FUNCTION
|| opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED || opcode == ZEND_DECLARE_CLASS_DELAYED
|| opcode == ZEND_DECLARE_ANON_CLASS || opcode == ZEND_DECLARE_ANON_INHERITED_CLASS || opcode == ZEND_FAST_RET || opcode == ZEND_TICKS || opcode == ZEND_DECLARE_ANON_CLASS || opcode == ZEND_FAST_RET || opcode == ZEND_TICKS
|| opcode == ZEND_EXT_STMT || opcode == ZEND_EXT_FCALL_BEGIN || opcode == ZEND_EXT_FCALL_END || opcode == ZEND_EXT_NOP || opcode == ZEND_BIND_GLOBAL || opcode == ZEND_EXT_STMT || opcode == ZEND_EXT_FCALL_BEGIN || opcode == ZEND_EXT_FCALL_END || opcode == ZEND_EXT_NOP || opcode == ZEND_BIND_GLOBAL
; ;
} }

View file

@ -14,7 +14,4 @@ class C extends UndefBase
--EXPECTF-- --EXPECTF--
In autoload: string(9) "UndefBase" In autoload: string(9) "UndefBase"
Fatal error: Uncaught Error: Class 'UndefBase' not found in %s:%d Fatal error: Class 'UndefBase' not found in %s on line %d
Stack trace:
#0 {main}
thrown in %sautoload_011.php on line %d

View file

@ -13,10 +13,4 @@ try {
?> ?>
--EXPECTF-- --EXPECTF--
bool(false) Fatal error: Class 'B' not found in %s on line %d
bool(false)
Fatal error: Uncaught Error: Class 'B' not found in %sbug75765.php:%d
Stack trace:
#0 {main}
thrown in %sbug75765.php on line %d