Skip to content

Commit 5aa2d47

Browse files
committed
Implement changes requested from code review
1 parent ff2e3a6 commit 5aa2d47

11 files changed

+56
-24
lines changed

Zend/tests/enum/backed-duplicate-int.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ enum Foo: int {
88
case Baz = 0;
99
}
1010

11+
var_dump(Foo::Bar);
12+
1113
?>
1214
--EXPECTF--
1315
Fatal error: Duplicate value in enum Foo for cases Bar and Baz in %s on line %s

Zend/tests/enum/backed-duplicate-string.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ enum Suit: string {
1010
case Spades = 'H';
1111
}
1212

13+
var_dump(Suit::Hearts);
14+
1315
?>
1416
--EXPECTF--
1517
Fatal error: Duplicate value in enum Suit for cases Hearts and Spades in %s on line %s

Zend/tests/enum/backed-mismatch.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ enum Foo: int {
77
case Bar = 'bar';
88
}
99

10+
var_dump(Foo::Bar);
11+
1012
?>
1113
--EXPECTF--
1214
Fatal error: Enum case type string does not match enum backing type int in %s on line %d

Zend/tests/enum/name-property.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var_dump(IntFoo::Bar->name);
2323
--EXPECT--
2424
array(1) {
2525
[0]=>
26-
object(ReflectionProperty)#4 (2) {
26+
object(ReflectionProperty)#2 (2) {
2727
["name"]=>
2828
string(4) "name"
2929
["class"]=>
@@ -33,14 +33,14 @@ array(1) {
3333
string(3) "Bar"
3434
array(2) {
3535
[0]=>
36-
object(ReflectionProperty)#5 (2) {
36+
object(ReflectionProperty)#3 (2) {
3737
["name"]=>
3838
string(4) "name"
3939
["class"]=>
4040
string(6) "IntFoo"
4141
}
4242
[1]=>
43-
object(ReflectionProperty)#6 (2) {
43+
object(ReflectionProperty)#4 (2) {
4444
["name"]=>
4545
string(5) "value"
4646
["class"]=>

Zend/tests/enum/update-class-constant-failure.phpt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ enum Foo: string {
77
const Bar = NONEXISTENT;
88
}
99

10+
var_dump(Foo::Bar);
11+
1012
?>
1113
--EXPECTF--
12-
Fatal error: During updating of class constants: Uncaught Error: Undefined constant "NONEXISTENT" in %s:%d
14+
Fatal error: Uncaught Error: Undefined constant "NONEXISTENT" in %s:%d
1315
Stack trace:
14-
#0 {main} in %s on line %d
16+
#0 {main}
17+
thrown in %s on line %d

Zend/zend_API.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "zend_closures.h"
3131
#include "zend_inheritance.h"
3232
#include "zend_ini.h"
33+
#include "zend_enum.h"
3334

3435
#include <stdarg.h>
3536

@@ -1503,6 +1504,10 @@ ZEND_API zend_result zend_update_class_constants(zend_class_entry *class_type) /
15031504
class_type->ce_flags = ce_flags;
15041505
}
15051506

1507+
if (class_type->ce_flags & ZEND_ACC_ENUM && class_type->enum_backing_type != IS_UNDEF) {
1508+
zend_enum_build_backed_enum_table(class_type);
1509+
}
1510+
15061511
return SUCCESS;
15071512
}
15081513
/* }}} */

Zend/zend_ast.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -778,20 +778,16 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast
778778
zend_ast *case_value_ast = ast->child[2];
779779

780780
zval case_value_zv;
781-
zval *case_value_zv_ptr = NULL;
781+
ZVAL_UNDEF(&case_value_zv);
782782
if (case_value_ast != NULL) {
783783
if (UNEXPECTED(zend_ast_evaluate(&case_value_zv, case_value_ast, scope) != SUCCESS)) {
784-
ret = FAILURE;
785-
break;
784+
return FAILURE;
786785
}
787-
case_value_zv_ptr = &case_value_zv;
788786
}
789787

790788
zend_class_entry *ce = zend_lookup_class(class_name);
791-
zend_enum_new(result, ce, case_name, case_value_zv_ptr);
792-
if (case_value_zv_ptr != NULL) {
793-
Z_TRY_DELREF_P(case_value_zv_ptr);
794-
}
789+
zend_enum_new(result, ce, case_name, case_value_ast != NULL ? &case_value_zv : NULL);
790+
zval_ptr_dtor_nogc(&case_value_zv);
795791
break;
796792
}
797793
case ZEND_AST_CLASS_CONST:

Zend/zend_enum.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,7 @@ void zend_enum_build_backed_enum_table(zend_class_entry *ce)
190190
uint32_t backing_type = ce->enum_backing_type;
191191
ZEND_ASSERT(backing_type != IS_UNDEF);
192192

193-
if (zend_update_class_constants(ce) == FAILURE) {
194-
zend_exception_uncaught_error("During updating of class constants");
195-
}
193+
ZEND_ASSERT(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED);
196194

197195
ce->backed_enum_table = emalloc(sizeof(HashTable));
198196
zend_hash_init(ce->backed_enum_table, 0, NULL, ZVAL_PTR_DTOR, 0);
@@ -268,6 +266,10 @@ static ZEND_NAMED_FUNCTION(zend_enum_cases_func)
268266

269267
ZEND_API zend_result zend_enum_get_case_by_value(zend_object **result, zend_class_entry *ce, zend_long long_key, zend_string *string_key, bool try)
270268
{
269+
if (!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
270+
zend_update_class_constants(ce);
271+
}
272+
271273
zval *case_name_zv;
272274
if (ce->enum_backing_type == IS_LONG) {
273275
case_name_zv = zend_hash_index_find(ce->backed_enum_table, long_key);

Zend/zend_inheritance.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2933,10 +2933,6 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
29332933
ZSTR_SET_CE_CACHE(ce->name, ce);
29342934
}
29352935

2936-
if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF) {
2937-
zend_enum_build_backed_enum_table(ce);
2938-
}
2939-
29402936
return ce;
29412937
}
29422938
/* }}} */

Zend/zend_vm_def.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5897,7 +5897,13 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO
58975897
}
58985898
value = &c->value;
58995899
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
5900-
zval_update_constant_ex(value, c->ce);
5900+
ce = c->ce;
5901+
if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF) {
5902+
// Enums require loading of all class constants to build the backed enum table
5903+
zend_update_class_constants(ce);
5904+
} else {
5905+
zval_update_constant_ex(value, ce);
5906+
}
59015907
if (UNEXPECTED(EG(exception) != NULL)) {
59025908
ZVAL_UNDEF(EX_VAR(opline->result.var));
59035909
HANDLE_EXCEPTION();

Zend/zend_vm_execute.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7066,7 +7066,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
70667066
}
70677067
value = &c->value;
70687068
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
7069-
zval_update_constant_ex(value, c->ce);
7069+
ce = c->ce;
7070+
if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF) {
7071+
// Enums require loading of all class constants to build the backed enum table
7072+
zend_update_class_constants(ce);
7073+
} else {
7074+
zval_update_constant_ex(value, ce);
7075+
}
70707076
if (UNEXPECTED(EG(exception) != NULL)) {
70717077
ZVAL_UNDEF(EX_VAR(opline->result.var));
70727078
HANDLE_EXCEPTION();
@@ -24611,7 +24617,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
2461124617
}
2461224618
value = &c->value;
2461324619
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
24614-
zval_update_constant_ex(value, c->ce);
24620+
ce = c->ce;
24621+
if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF) {
24622+
// Enums require loading of all class constants to build the backed enum table
24623+
zend_update_class_constants(ce);
24624+
} else {
24625+
zval_update_constant_ex(value, ce);
24626+
}
2461524627
if (UNEXPECTED(EG(exception) != NULL)) {
2461624628
ZVAL_UNDEF(EX_VAR(opline->result.var));
2461724629
HANDLE_EXCEPTION();
@@ -33449,7 +33461,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
3344933461
}
3345033462
value = &c->value;
3345133463
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
33452-
zval_update_constant_ex(value, c->ce);
33464+
ce = c->ce;
33465+
if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF) {
33466+
// Enums require loading of all class constants to build the backed enum table
33467+
zend_update_class_constants(ce);
33468+
} else {
33469+
zval_update_constant_ex(value, ce);
33470+
}
3345333471
if (UNEXPECTED(EG(exception) != NULL)) {
3345433472
ZVAL_UNDEF(EX_VAR(opline->result.var));
3345533473
HANDLE_EXCEPTION();

0 commit comments

Comments
 (0)