Skip to content

Commit 8b13efc

Browse files
oplanreBilge
authored andcommitted
Implement static classes
1 parent 1f64e7c commit 8b13efc

10 files changed

+37
-9
lines changed

Zend/Optimizer/escape_analysis.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ static bool is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, i
162162
script, op_array, opline);
163163
uint32_t forbidden_flags =
164164
/* These flags will always cause an exception */
165-
ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS
165+
ZEND_ACC_STATIC | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS
166166
| ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT;
167167
if (ce
168168
&& !ce->parent

Zend/zend_API.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1795,13 +1795,15 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties)
17951795
* calling zend_merge_properties(). */
17961796
static zend_always_inline zend_result _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties) /* {{{ */
17971797
{
1798-
if (UNEXPECTED(class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_ENUM))) {
1798+
if (UNEXPECTED(class_type->ce_flags & (ZEND_ACC_STATIC|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_ENUM))) {
17991799
if (class_type->ce_flags & ZEND_ACC_INTERFACE) {
18001800
zend_throw_error(NULL, "Cannot instantiate interface %s", ZSTR_VAL(class_type->name));
18011801
} else if (class_type->ce_flags & ZEND_ACC_TRAIT) {
18021802
zend_throw_error(NULL, "Cannot instantiate trait %s", ZSTR_VAL(class_type->name));
18031803
} else if (class_type->ce_flags & ZEND_ACC_ENUM) {
18041804
zend_throw_error(NULL, "Cannot instantiate enum %s", ZSTR_VAL(class_type->name));
1805+
} else if (class_type->ce_flags & ZEND_ACC_STATIC) {
1806+
zend_throw_error(NULL, "Cannot instantiate static class %s", ZSTR_VAL(class_type->name));
18051807
} else {
18061808
zend_throw_error(NULL, "Cannot instantiate abstract class %s", ZSTR_VAL(class_type->name));
18071809
}

Zend/zend_ast.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,6 +1837,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
18371837
if (decl->flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) {
18381838
smart_str_appends(str, "abstract ");
18391839
}
1840+
if (decl->flags & ZEND_ACC_STATIC) {
1841+
smart_str_appends(str, "static ");
1842+
}
18401843
if (decl->flags & ZEND_ACC_FINAL) {
18411844
smart_str_appends(str, "final ");
18421845
}

Zend/zend_compile.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,7 @@ uint32_t zend_add_class_modifier(uint32_t flags, uint32_t new_flag) /* {{{ */
931931
"Multiple abstract modifiers are not allowed", 0);
932932
return 0;
933933
}
934+
934935
if ((flags & ZEND_ACC_FINAL) && (new_flag & ZEND_ACC_FINAL)) {
935936
zend_throw_exception(zend_ce_compile_error, "Multiple final modifiers are not allowed", 0);
936937
return 0;
@@ -944,6 +945,12 @@ uint32_t zend_add_class_modifier(uint32_t flags, uint32_t new_flag) /* {{{ */
944945
"Cannot use the final modifier on an abstract class", 0);
945946
return 0;
946947
}
948+
if ((flags & ZEND_ACC_STATIC) && (new_flag & ZEND_ACC_STATIC)) {
949+
zend_throw_exception(zend_ce_compile_error,
950+
"Multiple static modifiers are not allowed", 0);
951+
return 0;
952+
}
953+
947954
return new_flags;
948955
}
949956
/* }}} */
@@ -960,6 +967,10 @@ uint32_t zend_add_anonymous_class_modifier(uint32_t flags, uint32_t new_flag)
960967
zend_throw_exception(zend_ce_compile_error, "Cannot use the final modifier on an anonymous class", 0);
961968
return 0;
962969
}
970+
if (new_flag & ZEND_ACC_STATIC) {
971+
zend_throw_exception(zend_ce_compile_error, "Cannot use the static modifier on an anonymous class", 0);
972+
return 0;
973+
}
963974
if ((flags & ZEND_ACC_READONLY_CLASS) && (new_flag & ZEND_ACC_READONLY_CLASS)) {
964975
zend_throw_exception(zend_ce_compile_error, "Multiple readonly modifiers are not allowed", 0);
965976
return 0;

Zend/zend_language_parser.y

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ class_modifier:
617617
T_ABSTRACT { $$ = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; }
618618
| T_FINAL { $$ = ZEND_ACC_FINAL; }
619619
| T_READONLY { $$ = ZEND_ACC_READONLY_CLASS|ZEND_ACC_NO_DYNAMIC_PROPERTIES; }
620+
| T_STATIC { $$ = ZEND_ACC_STATIC; }
620621
;
621622

622623
trait_declaration_statement:

ext/mysqli/mysqli.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
758758
if (ce == NULL) {
759759
ce = zend_standard_class_def;
760760
}
761-
if (UNEXPECTED(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
761+
if (UNEXPECTED(ce->ce_flags & (ZEND_ACC_STATIC|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
762762
zend_throw_error(NULL, "Class %s cannot be instantiated", ZSTR_VAL(ce->name));
763763
RETURN_THROWS();
764764
}

ext/reflection/php_reflection.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,9 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char
348348
if (ce->ce_flags & ZEND_ACC_READONLY_CLASS) {
349349
smart_str_append_printf(str, "readonly ");
350350
}
351+
if (ce->ce_flags & ZEND_ACC_STATIC) {
352+
smart_str_append_printf(str, "static ");
353+
}
351354
smart_str_append_printf(str, "class ");
352355
}
353356
smart_str_append_printf(str, "%s", ZSTR_VAL(ce->name));
@@ -4934,7 +4937,7 @@ ZEND_METHOD(ReflectionClass, isInstantiable)
49344937
RETURN_THROWS();
49354938
}
49364939
GET_REFLECTION_OBJECT_PTR(ce);
4937-
if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_ENUM)) {
4940+
if (ce->ce_flags & (ZEND_ACC_STATIC | ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_ENUM)) {
49384941
RETURN_FALSE;
49394942
}
49404943

@@ -4959,7 +4962,7 @@ ZEND_METHOD(ReflectionClass, isCloneable)
49594962
RETURN_THROWS();
49604963
}
49614964
GET_REFLECTION_OBJECT_PTR(ce);
4962-
if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_ENUM)) {
4965+
if (ce->ce_flags & (ZEND_ACC_STATIC | ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_ENUM)) {
49634966
RETURN_FALSE;
49644967
}
49654968
if (!Z_ISUNDEF(intern->obj)) {
@@ -5028,7 +5031,7 @@ ZEND_METHOD(ReflectionClass, getModifiers)
50285031
{
50295032
reflection_object *intern;
50305033
zend_class_entry *ce;
5031-
uint32_t keep_flags = ZEND_ACC_FINAL | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_READONLY_CLASS;
5034+
uint32_t keep_flags = ZEND_ACC_STATIC | ZEND_ACC_FINAL | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_READONLY_CLASS;
50325035

50335036
if (zend_parse_parameters_none() == FAILURE) {
50345037
RETURN_THROWS();
@@ -5433,7 +5436,7 @@ ZEND_METHOD(ReflectionClass, isIterable)
54335436

54345437
GET_REFLECTION_OBJECT_PTR(ce);
54355438

5436-
if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS |
5439+
if (ce->ce_flags & (ZEND_ACC_STATIC | ZEND_ACC_INTERFACE | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS |
54375440
ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
54385441
RETURN_FALSE;
54395442
}

ext/reflection/php_reflection.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ class ReflectionClass implements Reflector
249249
public const int IS_FINAL = UNKNOWN;
250250
/** @cvalue ZEND_ACC_READONLY_CLASS */
251251
public const int IS_READONLY = UNKNOWN;
252+
/** @cvalue ZEND_ACC_STATIC */
253+
public const int IS_STATIC = UNKNOWN;
252254

253255
public string $name;
254256

ext/reflection/php_reflection_arginfo.h

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

main/streams/userspace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ static zend_result call_method_if_exists(
260260

261261
static void user_stream_create_object(struct php_user_stream_wrapper *uwrap, php_stream_context *context, zval *object)
262262
{
263-
if (uwrap->ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
263+
if (uwrap->ce->ce_flags & (ZEND_ACC_STATIC|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
264264
ZVAL_UNDEF(object);
265265
return;
266266
}

0 commit comments

Comments
 (0)