Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 263f12a

Browse files
committed
Use zend_strings instead of HT
1 parent 2e48282 commit 263f12a

File tree

5 files changed

+61
-19
lines changed

5 files changed

+61
-19
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Multiple associated types
3+
--FILE--
4+
<?php
5+
6+
interface I {
7+
type K;
8+
type V;
9+
public function set(K $key, V $value): void;
10+
public function get(K $key): V;
11+
}
12+
13+
class C implements I {
14+
public function set(int $key, string $value): void {}
15+
public function get(int $key): string {}
16+
}
17+
18+
?>
19+
--EXPECTF--
20+
Fatal error: Declaration of C::set(int $key, string $value): void must be compatible with I::set(K $key, V $value): void in %s on line %d

‎Zend/zend.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ struct _zend_class_entry {
219219
HashTable *attributes;
220220

221221
/* Only for interfaces */
222-
HashTable *associated_types;
222+
zend_string **associated_types;
223+
uint32_t num_associated_types;
223224

224225
uint32_t enum_backing_type;
225226
HashTable *backed_enum_table;

‎Zend/zend_compile.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,6 +2073,7 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, bool nullify_hand
20732073
ce->properties_info_table = NULL;
20742074
ce->attributes = NULL;
20752075
ce->associated_types = NULL;
2076+
ce->num_associated_types = 0;
20762077
ce->enum_backing_type = IS_UNDEF;
20772078
ce->backed_enum_table = NULL;
20782079

@@ -7005,8 +7006,14 @@ static zend_type zend_compile_single_typename(zend_ast *ast)
70057006
if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
70067007
class_name = zend_resolve_class_name_ast(ast);
70077008
zend_assert_valid_class_name(class_name, "a type name");
7008-
if (ce && ce->associated_types && zend_hash_exists(ce->associated_types, class_name)) {
7009-
flags = _ZEND_TYPE_ASSOCIATED_BIT;
7009+
if (ce && ce->associated_types) {
7010+
for (uint32_t i = 0; i < ce->num_associated_types; i++) {
7011+
const zend_string *cur = ce->associated_types[i];
7012+
if (zend_string_equals(class_name, cur)) {
7013+
flags = _ZEND_TYPE_ASSOCIATED_BIT;
7014+
break;
7015+
}
7016+
}
70107017
}
70117018
} else {
70127019
ZEND_ASSERT(fetch_type == ZEND_FETCH_CLASS_SELF || fetch_type == ZEND_FETCH_CLASS_PARENT);
@@ -9035,9 +9042,9 @@ static void zend_compile_use_trait(zend_ast *ast) /* {{{ */
90359042

90369043

90379044

9038-
static void zend_compile_associated_type(zend_ast *ast) {
9045+
static void zend_compile_associated_type(constzend_ast *ast) {
90399046
zend_class_entry *ce = CG(active_class_entry);
9040-
HashTable*associated_types = ce->associated_types;
9047+
zend_string**associated_types = ce->associated_types;
90419048
zend_ast *name_ast = ast->child[0];
90429049
zend_string *name = zend_ast_get_str(name_ast);
90439050

@@ -9047,19 +9054,26 @@ static void zend_compile_associated_type(zend_ast *ast) {
90479054
}
90489055

90499056
ZEND_ASSERT(name != NULL);
9050-
bool persistent = false; // TODO I need to figure this out
9057+
// TODO This is very jank
9058+
const bool persistent = ce->type == ZEND_INTERNAL_CLASS;
90519059
if (associated_types == NULL) {
9052-
ce->associated_types = pemalloc(sizeof(HashTable), persistent);
9053-
zend_hash_init(ce->associated_types, 8, NULL, NULL, persistent);
9054-
associated_types = ce->associated_types;
9060+
ce->associated_types = pemalloc(sizeof(zend_string*), persistent);
9061+
ce->associated_types[0] = zend_string_copy(name);
9062+
ce->num_associated_types = 1;
9063+
return;
90559064
}
9056-
if (zend_hash_exists(associated_types, name)) {
9057-
zend_error_noreturn(E_COMPILE_ERROR,
9058-
"Cannot have two associated types with the same name \"%s\"", ZSTR_VAL(name));
9065+
for (uint32_t i = 0; i < ce->num_associated_types; i++) {
9066+
const zend_string *cur = ce->associated_types[i];
9067+
if (zend_string_equals(name, cur)) {
9068+
zend_error_noreturn(E_COMPILE_ERROR,
9069+
"Cannot have two associated types with the same name \"%s\"", ZSTR_VAL(name));
9070+
return;
9071+
}
90599072
}
9060-
zval tmp;
9061-
ZVAL_UNDEF(&tmp);
9062-
zend_hash_add_new(associated_types, name, &tmp);
9073+
uint32_t new_size = ce->num_associated_types + 1;
9074+
ce->associated_types = perealloc(ce->associated_types, new_size * sizeof(zend_string*), persistent);
9075+
ce->associated_types[ce->num_associated_types] = zend_string_copy(name);
9076+
ce->num_associated_types = new_size;
90639077
}
90649078

90659079
static void zend_compile_implements(zend_ast *ast) /* {{{ */

‎Zend/zend_inheritance.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ ZEND_API inheritance_status zend_perform_covariant_type_check(
708708

709709
if (ZEND_TYPE_IS_ASSOCIATED(proto_type)) {
710710
return zend_is_type_subtype_of_associated_type(
711-
fe_scope, fe_type_ptr, proto_type_ptr, proto_scope->associated_types);
711+
fe_scope, fe_type_ptr, proto_type_ptr, NULL);
712712
}
713713

714714
/* Builtin types may be removed, but not added */

‎Zend/zend_opcode.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,10 @@ ZEND_API void destroy_zend_class(zval *zv)
352352
}
353353

354354
if (ce->associated_types) {
355-
zend_hash_release(ce->associated_types);
355+
for (uint32_t i = 0; i < ce->num_associated_types; i++) {
356+
zend_string_release(ce->associated_types[i]);
357+
}
358+
efree(ce->associated_types);
356359
}
357360

358361
if (ce->num_interfaces > 0 && !(ce->ce_flags & ZEND_ACC_RESOLVED_INTERFACES)) {
@@ -531,9 +534,13 @@ ZEND_API void destroy_zend_class(zval *zv)
531534
if (ce->attributes) {
532535
zend_hash_release(ce->attributes);
533536
}
534-
if (ce->associated_types) {
535-
zend_hash_release(ce->associated_types);
537+
538+
if (ce->associated_types) {
539+
for (uint32_t i = 0; i < ce->num_associated_types; i++) {
540+
zend_string_release(ce->associated_types[i]);
536541
}
542+
pefree(ce->associated_types, true);
543+
}
537544
free(ce);
538545
break;
539546
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /