Skip to content

Commit 8a2178f

Browse files
committed
Ensure that typed class constants work correctly
1 parent db2d990 commit 8a2178f

File tree

4 files changed

+37
-22
lines changed

4 files changed

+37
-22
lines changed

src/copy.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ static zend_op* pmmpthread_copy_opcodes(zend_op_array *op_array, zval *literals,
452452
} /* }}} */
453453

454454
/* {{{ */
455-
static void pmmpthread_copy_zend_type(const zend_type *old_type, zend_type *new_type) {
455+
void pmmpthread_copy_zend_type(const zend_type *old_type, zend_type *new_type) {
456456
memcpy(new_type, old_type, sizeof(zend_type));
457457

458458
//This code is based on zend_persist_type() in ext/opcache/zend_persist.c

src/copy.h

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <src/pmmpthread.h>
2222
#include <src/thread.h>
2323
#include <Zend/zend_attributes.h>
24+
#include <Zend/zend_types.h>
2425
#include <src/prepare.h>
2526

2627
/* {{{ */
@@ -32,6 +33,9 @@ int pmmpthread_copy_zval(const pmmpthread_ident_t* owner, zval* dest, zval* sour
3233
/* {{{ */
3334
HashTable* pmmpthread_copy_attributes(const pmmpthread_ident_t* owner, HashTable *attributes, zend_string *filename); /* }}} */
3435

36+
/* {{{ */
37+
void pmmpthread_copy_zend_type(const zend_type* old_type, zend_type* new_type); /* }}} */
38+
3539
/* {{{ */
3640
zend_function* pmmpthread_copy_function(const pmmpthread_ident_t* owner, const zend_function *function); /* }}} */
3741

src/prepare.c

+6-21
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ static void prepare_class_constants(const pmmpthread_ident_t* source, zend_class
104104
if (zc->attributes) {
105105
rc->attributes = pmmpthread_copy_attributes(source, zc->attributes, zc->ce->type == ZEND_INTERNAL_CLASS ? NULL : zc->ce->info.user.filename);
106106
}
107+
108+
#if PHP_VERSION_ID >= 80300
109+
pmmpthread_copy_zend_type(&zc->type, &rc->type);
110+
#endif
111+
107112
} ZEND_HASH_FOREACH_END();
108113
} /* }}} */
109114

@@ -205,27 +210,7 @@ static void prepare_class_property_table(const pmmpthread_ident_t* source, zend_
205210
} else dup->ce = pmmpthread_prepared_entry(source, info->ce);
206211
}
207212

208-
memcpy(&dup->type, &info->type, sizeof(zend_type));
209-
210-
//This code is based on zend_persist_type() in ext/opcache/zend_persist.c
211-
if (ZEND_TYPE_HAS_LIST(info->type)) {
212-
const zend_type_list *old_list = ZEND_TYPE_LIST(info->type);
213-
zend_type_list *new_list;
214-
if (ZEND_TYPE_USES_ARENA(info->type)) {
215-
new_list = zend_arena_alloc(&CG(arena), ZEND_TYPE_LIST_SIZE(old_list->num_types));
216-
} else {
217-
new_list = emalloc(ZEND_TYPE_LIST_SIZE(old_list->num_types));
218-
}
219-
memcpy(new_list, old_list, ZEND_TYPE_LIST_SIZE(old_list->num_types));
220-
ZEND_TYPE_SET_PTR(dup->type, new_list);
221-
}
222-
223-
zend_type *single_type;
224-
ZEND_TYPE_FOREACH(dup->type, single_type) {
225-
if (ZEND_TYPE_HAS_NAME(*single_type)) {
226-
ZEND_TYPE_SET_PTR(*single_type, pmmpthread_copy_string(ZEND_TYPE_NAME(*single_type)));
227-
}
228-
} ZEND_TYPE_FOREACH_END();
213+
pmmpthread_copy_zend_type(&info->type, &dup->type);
229214

230215
if (info->attributes) {
231216
dup->attributes = pmmpthread_copy_attributes(source, info->attributes, info->ce->type == ZEND_INTERNAL_CLASS ? NULL : info->ce->info.user.filename);

tests/typed-class-constants.phpt

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Test that class constant types are copied correctly
3+
--SKIPIF--
4+
<?php if(PHP_VERSION_ID < 80300) die("skip this test is for 8.3+ only"); ?>
5+
--FILE--
6+
<?php
7+
8+
use pmmp\thread\Thread;
9+
10+
class Test{
11+
public const int TEST = 1;
12+
}
13+
14+
$thread = new class extends Thread{
15+
public function run() : void{
16+
$reflect = new \ReflectionClass(Test::class);
17+
$const = $reflect->getReflectionConstant("TEST");
18+
var_dump($const->getType()->getName());
19+
var_dump($const->getType()->allowsNull());
20+
}
21+
};
22+
$thread->start(Thread::INHERIT_ALL) && $thread->join();
23+
?>
24+
--EXPECT--
25+
string(3) "int"
26+
bool(false)

0 commit comments

Comments
 (0)