diff options
author | Dmitry Stogov <dmitry@zend.com> | 2015-04-27 17:18:35 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2015-04-27 17:18:35 +0300 |
commit | 5af7743cf58056543886f9b2af183be2acac4e78 (patch) | |
tree | 842321edba852f4f03e2700f1502e724c7eee998 /Zend | |
parent | ffe804a50c687673e2c46a0d4a43ab5eb3604281 (diff) | |
parent | 8acd7f49dafa9b9743d2921b3f3e49503d9fe342 (diff) | |
download | php-git-5af7743cf58056543886f9b2af183be2acac4e78.tar.gz |
Merge branch 'anon'
* anon:
Pass class_entry through IS_VAR to avoid hash lookup in ZEND_NEW.
Use "safe" anonymous class names. Don't show the mangled names through var_dump().
Refactored using specialized opcodes
Fix implementing_class handling
More cleanup (mainly retab)
Don't issue FETCH_CLASS for anon classes
More retab
Simply anon class name generation
Retab
Revert unrelated changes / rebase fixup
Rebase Joe's anon classes implementation
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/tests/anon/001.phpt | 10 | ||||
-rw-r--r-- | Zend/tests/anon/002.phpt | 21 | ||||
-rw-r--r-- | Zend/tests/anon/003.phpt | 54 | ||||
-rw-r--r-- | Zend/tests/anon/004.phpt | 30 | ||||
-rw-r--r-- | Zend/tests/anon/005.phpt | 36 | ||||
-rw-r--r-- | Zend/tests/anon/006.phpt | 15 | ||||
-rw-r--r-- | Zend/tests/anon/007.phpt | 23 | ||||
-rw-r--r-- | Zend/tests/anon/008.phpt | 23 | ||||
-rw-r--r-- | Zend/tests/anon/009.phpt | 18 | ||||
-rw-r--r-- | Zend/tests/anon/010.phpt | 23 | ||||
-rw-r--r-- | Zend/zend_ast.c | 4 | ||||
-rw-r--r-- | Zend/zend_compile.c | 86 | ||||
-rw-r--r-- | Zend/zend_compile.h | 2 | ||||
-rw-r--r-- | Zend/zend_language_parser.y | 15 | ||||
-rw-r--r-- | Zend/zend_opcode.c | 4 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 42 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 92 | ||||
-rw-r--r-- | Zend/zend_vm_opcodes.c | 4 | ||||
-rw-r--r-- | Zend/zend_vm_opcodes.h | 2 |
19 files changed, 489 insertions, 15 deletions
diff --git a/Zend/tests/anon/001.phpt b/Zend/tests/anon/001.phpt new file mode 100644 index 0000000000..75589550a8 --- /dev/null +++ b/Zend/tests/anon/001.phpt @@ -0,0 +1,10 @@ +--TEST-- +declare bare anonymous class +--FILE-- +<?php +var_dump(new class{}); +--EXPECTF-- +object(class@%s)#%d (0) { +} + + diff --git a/Zend/tests/anon/002.phpt b/Zend/tests/anon/002.phpt new file mode 100644 index 0000000000..1cbaf81a9f --- /dev/null +++ b/Zend/tests/anon/002.phpt @@ -0,0 +1,21 @@ +--TEST-- +declare anonymous class extending another +--FILE-- +<?php +class A{} + +interface B{ + public function method(); +} + +$a = new class extends A implements B { + public function method(){ + return true; + } +}; + +var_dump($a instanceof A, $a instanceof B); +--EXPECTF-- +bool(true) +bool(true) + diff --git a/Zend/tests/anon/003.phpt b/Zend/tests/anon/003.phpt new file mode 100644 index 0000000000..ac023f43a5 --- /dev/null +++ b/Zend/tests/anon/003.phpt @@ -0,0 +1,54 @@ +--TEST-- +reusing anonymous classes +--FILE-- +<?php +while (@$i++<10) { + var_dump(new class($i) { + + public function __construct($i) { + $this->i = $i; + } + }); +} +--EXPECTF-- +object(class@%s)#1 (1) { + ["i"]=> + int(1) +} +object(class@%s)#1 (1) { + ["i"]=> + int(2) +} +object(class@%s)#1 (1) { + ["i"]=> + int(3) +} +object(class@%s)#1 (1) { + ["i"]=> + int(4) +} +object(class@%s)#1 (1) { + ["i"]=> + int(5) +} +object(class@%s)#1 (1) { + ["i"]=> + int(6) +} +object(class@%s)#1 (1) { + ["i"]=> + int(7) +} +object(class@%s)#1 (1) { + ["i"]=> + int(8) +} +object(class@%s)#1 (1) { + ["i"]=> + int(9) +} +object(class@%s)#1 (1) { + ["i"]=> + int(10) +} + diff --git a/Zend/tests/anon/004.phpt b/Zend/tests/anon/004.phpt new file mode 100644 index 0000000000..f72e7255de --- /dev/null +++ b/Zend/tests/anon/004.phpt @@ -0,0 +1,30 @@ +--TEST-- +testing anonymous inheritance +--FILE-- +<?php +class Outer { + protected $data; + + public function __construct($data) { + $this->data = $data; + } + + public function getArrayAccess() { + /* create a proxy object implementing array access */ + return new class($this->data) extends Outer implements ArrayAccess { + public function offsetGet($offset) { return $this->data[$offset]; } + public function offsetSet($offset, $data) { return ($this->data[$offset] = $data); } + public function offsetUnset($offset) { unset($this->data[$offset]); } + public function offsetExists($offset) { return isset($this->data[$offset]); } + }; + } +} + +$outer = new Outer(array( + rand(1, 100) +)); + +/* not null because inheritance */ +var_dump($outer->getArrayAccess()[0]); +--EXPECTF-- +int(%d) diff --git a/Zend/tests/anon/005.phpt b/Zend/tests/anon/005.phpt new file mode 100644 index 0000000000..7f1ff0755a --- /dev/null +++ b/Zend/tests/anon/005.phpt @@ -0,0 +1,36 @@ +--TEST-- +testing reusing anons that implement an interface +--FILE-- +<?php +class Outer { + protected $data; + + public function __construct(&$data) { + /* array access will be implemented by the time we get to here */ + $this->data = &$data; + } + + public function getArrayAccess() { + /* create a child object implementing array access */ + /* this grants you access to protected methods and members */ + return new class($this->data) implements ArrayAccess { + public function offsetGet($offset) { return $this->data[$offset]; } + public function offsetSet($offset, $data) { return ($this->data[$offset] = $data); } + public function offsetUnset($offset) { unset($this->data[$offset]); } + public function offsetExists($offset) { return isset($this->data[$offset]); } + }; + } +} + +$data = array( + rand(1, 100), + rand(2, 200) +); + +$outer = new Outer($data); +$proxy = $outer->getArrayAccess(); + +/* null because no inheritance, so no access to protected member */ +var_dump(@$outer->getArrayAccess()[0]); +--EXPECT-- +NULL diff --git a/Zend/tests/anon/006.phpt b/Zend/tests/anon/006.phpt new file mode 100644 index 0000000000..e5dc1226d8 --- /dev/null +++ b/Zend/tests/anon/006.phpt @@ -0,0 +1,15 @@ +--TEST-- +testing anon classes inside namespaces +--FILE-- +<?php +namespace lone { + $hello = new class{} ; +} + +namespace { + var_dump ($hello); +} +--EXPECTF-- +object(lone\class@%s)#1 (0) { +} + diff --git a/Zend/tests/anon/007.phpt b/Zend/tests/anon/007.phpt new file mode 100644 index 0000000000..12f4da6653 --- /dev/null +++ b/Zend/tests/anon/007.phpt @@ -0,0 +1,23 @@ +--TEST-- +testing anon classes in functions outside of classes in namespaces +--FILE-- +<?php +namespace lone { + function my_factory() { + return new class{}; + } + + class Outer { + + public function __construct() { + var_dump( + my_factory()); + } + } + + new Outer(); +} +--EXPECTF-- +object(lone\class@%s)#2 (0) { +} + diff --git a/Zend/tests/anon/008.phpt b/Zend/tests/anon/008.phpt new file mode 100644 index 0000000000..315163ca5f --- /dev/null +++ b/Zend/tests/anon/008.phpt @@ -0,0 +1,23 @@ +--TEST-- +testing static access for methods and properties in anon classes +--FILE-- +<?php +$anonClass = new class("cats", "dogs") { + public static $foo; + private static $bar; + + public function __construct($foo, $bar) { + static::$foo = $foo; + static::$bar = $bar; + } + + public static function getBar() { + return static::$bar; + } +}; + +var_dump($anonClass::$foo); +var_dump($anonClass::getBar()); +--EXPECT-- +string(4) "cats" +string(4) "dogs" diff --git a/Zend/tests/anon/009.phpt b/Zend/tests/anon/009.phpt new file mode 100644 index 0000000000..4a67cdd30d --- /dev/null +++ b/Zend/tests/anon/009.phpt @@ -0,0 +1,18 @@ +--TEST-- +testing traits in anon classes +--FILE-- +<?php + +trait Foo { + public function someMethod() { + return "bar"; + } +} + +$anonClass = new class { + use Foo; +}; + +var_dump($anonClass->someMethod()); +--EXPECT-- +string(3) "bar" diff --git a/Zend/tests/anon/010.phpt b/Zend/tests/anon/010.phpt new file mode 100644 index 0000000000..917989a7e2 --- /dev/null +++ b/Zend/tests/anon/010.phpt @@ -0,0 +1,23 @@ +--TEST-- +Trait binding after anon class +--FILE-- +<?php + +trait T { + public function m1() { return 42; } +} + +class C { + public function m2() { + return new class {}; + } + + use T; +} + +$c = new C; +var_dump($c->m1()); + +?> +--EXPECT-- +int(42) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 4eaad31a74..34a2e132f9 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -457,7 +457,9 @@ static void zend_ast_destroy_ex(zend_ast *ast, zend_bool free) { case ZEND_AST_CLASS: { zend_ast_decl *decl = (zend_ast_decl *) ast; - zend_string_release(decl->name); + if (decl->name) { + zend_string_release(decl->name); + } if (decl->doc_comment) { zend_string_release(decl->doc_comment); } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 65677f7d47..ddd1346d81 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -27,6 +27,7 @@ #include "zend_llist.h" #include "zend_API.h" #include "zend_exceptions.h" +#include "zend_interfaces.h" #include "zend_virtual_cwd.h" #include "zend_multibyte.h" #include "zend_language_scanner.h" @@ -3228,6 +3229,8 @@ void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type) /* {{ } /* }}} */ +zend_class_entry *zend_compile_class_decl(zend_ast *ast); + void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *class_ast = ast->child[0]; @@ -3240,6 +3243,17 @@ void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */ if (zend_is_const_default_class_ref(class_ast)) { class_node.op_type = IS_CONST; ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); + } else if (class_ast->kind == ZEND_AST_CLASS) { + uint32_t dcl_opnum = get_next_op_number(CG(active_op_array)); + zend_class_entry *ce = zend_compile_class_decl(class_ast); + /* jump over anon class declaration */ + opline = &CG(active_op_array)->opcodes[dcl_opnum]; + if (opline->opcode == ZEND_FETCH_CLASS) { + opline++; + } + class_node.op_type = opline->result_type; + class_node.u.op.var = opline->result.var; + opline->op1.opline_num = get_next_op_number(CG(active_op_array)); } else { zend_compile_class_ref(&class_node, class_ast, 1); } @@ -4884,7 +4898,28 @@ void zend_compile_implements(znode *class_node, zend_ast *ast) /* {{{ */ } /* }}} */ -void zend_compile_class_decl(zend_ast *ast) /* {{{ */ +static zend_string *zend_generate_anon_class_name(unsigned char *lex_pos) /* {{{ */ +{ + zend_string *result; + char char_pos_buf[32]; + size_t filename_len, char_pos_len = zend_sprintf(char_pos_buf, "%p", lex_pos); + + const char *filename; + if (CG(active_op_array)->filename) { + filename = CG(active_op_array)->filename->val; + filename_len = CG(active_op_array)->filename->len; + } else { + filename = "-"; + filename_len = sizeof("-") - 1; + } + /* NULL, name length, filename length, last accepting char position length */ + result = zend_string_alloc(sizeof("class@anonymous") + filename_len + char_pos_len, 0); + sprintf(result->val, "class@anonymous%c%s%s", '\0', filename, char_pos_buf); + return zend_new_interned_string(result); +} +/* }}} */ + +zend_class_entry *zend_compile_class_decl(zend_ast *ast) /* {{{ */ { zend_ast_decl *decl = (zend_ast_decl *) ast; zend_ast *extends_ast = decl->child[0]; @@ -4896,9 +4931,20 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ zend_op *opline; znode declare_node, extends_node; - if (CG(active_class_entry)) { - zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be nested"); - return; + zend_class_entry *original_ce = CG(active_class_entry); + znode original_implementing_class = FC(implementing_class); + + if (decl->flags & ZEND_ACC_ANON_CLASS) { + decl->name = name = zend_generate_anon_class_name(decl->lex_pos); + + /* Serialization is not supported for anonymous classes */ + ce->serialize = zend_class_serialize_deny; + ce->unserialize = zend_class_unserialize_deny; + } + + if (CG(active_class_entry) && !(decl->flags & ZEND_ACC_ANON_CLASS)) { + zend_error(E_COMPILE_ERROR, "Class declarations may not be nested"); + return NULL; } zend_assert_valid_class_name(name); @@ -4957,15 +5003,28 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ opline->op2_type = IS_CONST; LITERAL_STR(opline->op2, lcname); - if (extends_ast) { - opline->opcode = ZEND_DECLARE_INHERITED_CLASS; - opline->extended_value = extends_node.u.op.var; + if (decl->flags & ZEND_ACC_ANON_CLASS) { + if (extends_ast) { + opline->opcode = ZEND_DECLARE_ANON_INHERITED_CLASS; + opline->extended_value = extends_node.u.op.var; + } else { + opline->opcode = ZEND_DECLARE_ANON_CLASS; + } + + opline->op1_type = IS_UNUSED; + + zend_hash_update_ptr(CG(class_table), lcname, ce); } else { - opline->opcode = ZEND_DECLARE_CLASS; - } + zend_string *key; - { - zend_string *key = zend_build_runtime_definition_key(lcname, decl->lex_pos); + if (extends_ast) { + opline->opcode = ZEND_DECLARE_INHERITED_CLASS; + opline->extended_value = extends_node.u.op.var; + } else { + opline->opcode = ZEND_DECLARE_CLASS; + } + + key = zend_build_runtime_definition_key(lcname, decl->lex_pos); opline->op1_type = IS_CONST; LITERAL_STR(opline->op1, key); @@ -5051,7 +5110,10 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ ce->ce_flags |= ZEND_ACC_IMPLEMENT_INTERFACES; } - CG(active_class_entry) = NULL; + FC(implementing_class) = original_implementing_class; + CG(active_class_entry) = original_ce; + + return ce; } /* }}} */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index efc2f820e1..575dbe0803 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -206,6 +206,8 @@ typedef struct _zend_try_catch_element { #define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS 0x20 #define ZEND_ACC_INTERFACE 0x40 #define ZEND_ACC_TRAIT 0x80 +#define ZEND_ACC_ANON_CLASS 0x100 +#define ZEND_ACC_ANON_BOUND 0x200 /* method flags (visibility) */ /* The order of those must be kept - public < protected < private */ diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 0aba081218..2541c9f571 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -241,7 +241,8 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type <ast> extends_from parameter optional_type argument expr_without_variable global_var %type <ast> static_var class_statement trait_adaptation trait_precedence trait_alias %type <ast> absolute_trait_method_reference trait_method_reference property echo_expr -%type <ast> new_expr class_name class_name_reference simple_variable internal_functions_in_yacc +%type <ast> new_expr anonymous_class class_name class_name_reference simple_variable +%type <ast> internal_functions_in_yacc %type <ast> exit_expr scalar backticks_expr lexical_var function_call member_name %type <ast> variable_class_name dereferencable_scalar class_name_scalar constant dereferencable %type <ast> callable_expr callable_variable static_member new_variable @@ -798,9 +799,21 @@ non_empty_for_exprs: | expr { $$ = zend_ast_create_list(1, ZEND_AST_EXPR_LIST, $1); } ; +anonymous_class: + T_CLASS { $<num>$ = CG(zend_lineno); } ctor_arguments + extends_from implements_list backup_doc_comment '{' class_statement_list '}' { + zend_ast *decl = zend_ast_create_decl( + ZEND_AST_CLASS, ZEND_ACC_ANON_CLASS, $<num>2, $6, NULL, + $4, $5, $8, NULL); + $$ = zend_ast_create(ZEND_AST_NEW, decl, $3); + } +; + new_expr: T_NEW class_name_reference ctor_arguments { $$ = zend_ast_create(ZEND_AST_NEW, $2, $3); } + | T_NEW anonymous_class + { $$ = $2; } ; expr_without_variable: diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 8bdaded38f..98734dc533 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -761,6 +761,9 @@ ZEND_API int pass_two(zend_op_array *op_array) opline->result.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->result.var); } switch (opline->opcode) { + case ZEND_DECLARE_ANON_INHERITED_CLASS: + ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1); + /* break omitted intentionally */ case ZEND_DECLARE_INHERITED_CLASS: case ZEND_DECLARE_INHERITED_CLASS_DELAYED: opline->extended_value = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->extended_value); @@ -772,6 +775,7 @@ ZEND_API int pass_two(zend_op_array *op_array) /* break omitted intentionally */ case ZEND_JMP: case ZEND_FAST_CALL: + case ZEND_DECLARE_ANON_CLASS: ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1); break; case ZEND_JMPZNZ: diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index e16cbd5529..6565324c4c 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -6752,6 +6752,48 @@ ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, ANY) ZEND_VM_NEXT_OPCODE(); } +ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ANY, ANY) +{ + zend_class_entry *ce; + USE_OPLINE + + SAVE_OPLINE(); + ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op2))); + Z_CE_P(EX_VAR(opline->result.var)) = ce; + ZEND_ASSERT(ce != NULL); + + if (ce->ce_flags & ZEND_ACC_ANON_BOUND) { + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op1)); + } + + if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) { + zend_verify_abstract_class(ce); + } + ce->ce_flags |= ZEND_ACC_ANON_BOUND; + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_HANDLER(172, ZEND_DECLARE_ANON_INHERITED_CLASS, ANY, ANY) +{ + zend_class_entry *ce; + USE_OPLINE + + SAVE_OPLINE(); + ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op2))); + Z_CE_P(EX_VAR(opline->result.var)) = ce; + ZEND_ASSERT(ce != NULL); + + if (ce->ce_flags & ZEND_ACC_ANON_BOUND) { + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op1)); + } + + zend_do_inheritance(ce, Z_CE_P(EX_VAR(opline->extended_value))); + ce->ce_flags |= ZEND_ACC_ANON_BOUND; + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_HANDLER(141, ZEND_DECLARE_FUNCTION, ANY, ANY) { USE_OPLINE diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2802c6015c..18f4e8584a 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1334,6 +1334,48 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_INHERITED_CLASS_DELAYE ZEND_VM_NEXT_OPCODE(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_class_entry *ce; + USE_OPLINE + + SAVE_OPLINE(); + ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op2))); + Z_CE_P(EX_VAR(opline->result.var)) = ce; + ZEND_ASSERT(ce != NULL); + + if (ce->ce_flags & ZEND_ACC_ANON_BOUND) { + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op1)); + } + + if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) { + zend_verify_abstract_class(ce); + } + ce->ce_flags |= ZEND_ACC_ANON_BOUND; + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_class_entry *ce; + USE_OPLINE + + SAVE_OPLINE(); + ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op2))); + Z_CE_P(EX_VAR(opline->result.var)) = ce; + ZEND_ASSERT(ce != NULL); + + if (ce->ce_flags & ZEND_ACC_ANON_BOUND) { + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op1)); + } + + zend_do_inheritance(ce, Z_CE_P(EX_VAR(opline->extended_value))); + ce->ce_flags |= ZEND_ACC_ANON_BOUND; + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_FUNCTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -48760,6 +48802,56 @@ void zend_init_opcodes_handlers(void) ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_SPACESHIP_SPEC_CV_CV_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, ZEND_NULL_HANDLER }; zend_opcode_handlers = labels; diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index e8337404bb..95b8b859eb 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -21,7 +21,7 @@ #include <stdio.h> #include <zend.h> -const char *zend_vm_opcodes_map[171] = { +const char *zend_vm_opcodes_map[173] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -193,6 +193,8 @@ const char *zend_vm_opcodes_map[171] = { "ZEND_BIND_GLOBAL", "ZEND_COALESCE", "ZEND_SPACESHIP", + "ZEND_DECLARE_ANON_CLASS", + "ZEND_DECLARE_ANON_INHERITED_CLASS", }; ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) { diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index a5620370bb..89a0d3139b 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -203,5 +203,7 @@ END_EXTERN_C() #define ZEND_BIND_GLOBAL 168 #define ZEND_COALESCE 169 #define ZEND_SPACESHIP 170 +#define ZEND_DECLARE_ANON_CLASS 171 +#define ZEND_DECLARE_ANON_INHERITED_CLASS 172 #endif |