Skip to content

Commit 9923078

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: zend_weakrefs
2 parents dbcdf85 + 6529d7a commit 9923078

16 files changed

+394
-4
lines changed

Zend/tests/weakrefs/weakrefs_001.phpt

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
WeakReference
3+
--FILE--
4+
<?php
5+
$std = new stdClass;
6+
7+
debug_zval_dump($std);
8+
9+
$wr = WeakReference::create($std);
10+
$wr2 = WeakReference::create($std);
11+
12+
debug_zval_dump($std);
13+
14+
var_dump($wr, $wr2);
15+
16+
debug_zval_dump($wr->get());
17+
debug_zval_dump($wr2->get());
18+
19+
unset($std);
20+
21+
debug_zval_dump($wr->get());
22+
debug_zval_dump($wr2->get());
23+
?>
24+
--EXPECT--
25+
object(stdClass)#1 (0) refcount(2){
26+
}
27+
object(stdClass)#1 (0) refcount(2){
28+
}
29+
object(WeakReference)#2 (0) {
30+
}
31+
object(WeakReference)#2 (0) {
32+
}
33+
object(stdClass)#1 (0) refcount(2){
34+
}
35+
object(stdClass)#1 (0) refcount(2){
36+
}
37+
NULL
38+
NULL
39+

Zend/tests/weakrefs/weakrefs_002.phpt

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
WeakReference serials
3+
--FILE--
4+
<?php
5+
$wr = WeakReference::create(new stdClass);
6+
7+
try {
8+
serialize($wr);
9+
} catch (Exception $ex) {
10+
var_dump($ex->getMessage());
11+
}
12+
13+
$wrs = 'O:13:"WeakReference":0:{}';
14+
15+
var_dump(@unserialize($wrs));
16+
?>
17+
--EXPECT--
18+
string(47) "Serialization of 'WeakReference' is not allowed"
19+
bool(false)

Zend/tests/weakrefs/weakrefs_003.phpt

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
WeakReference object handlers
3+
--FILE--
4+
<?php
5+
$wr = WeakReference::create(new stdClass);
6+
7+
try {
8+
$wr->disallow;
9+
} catch (Error $ex) {
10+
var_dump($ex->getMessage());
11+
}
12+
13+
try {
14+
$wr->disallow = "writes";
15+
} catch (Error $ex) {
16+
var_dump($ex->getMessage());
17+
}
18+
19+
try {
20+
isset($wr->disallow);
21+
} catch (Error $ex) {
22+
var_dump($ex->getMessage());
23+
}
24+
25+
try {
26+
unset($wr->disallow);
27+
} catch (Error $ex) {
28+
var_dump($ex->getMessage());
29+
}
30+
31+
try {
32+
$disallow = &$wr->disallowed;
33+
} catch (Error $ex) {
34+
var_dump($ex->getMessage());
35+
}
36+
?>
37+
--EXPECT--
38+
string(47) "WeakReference objects do not support properties"
39+
string(47) "WeakReference objects do not support properties"
40+
string(47) "WeakReference objects do not support properties"
41+
string(47) "WeakReference objects do not support properties"
42+
string(56) "WeakReference objects do not support property references"
43+

Zend/tests/weakrefs/weakrefs_004.phpt

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
--TEST--
2+
WeakReference no inheritance
3+
--FILE--
4+
<?php
5+
class Test extends WeakReference {}
6+
?>
7+
--EXPECTF--
8+
Fatal error: Class Test may not inherit from final class (WeakReference) in %s on line %d

Zend/tests/weakrefs/weakrefs_005.phpt

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
WeakReference no __construct
3+
--FILE--
4+
<?php
5+
new WeakReference();
6+
?>
7+
--EXPECTF--
8+
Fatal error: Uncaught Error: Direct instantiation of 'WeakReference' is not allowed, use WeakReference::create instead in %s:2
9+
Stack trace:
10+
#0 %s(2): WeakReference->__construct()
11+
#1 {main}
12+
thrown in %s on line 2

Zend/zend_default_classes.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include "zend_exceptions.h"
2525
#include "zend_closures.h"
2626
#include "zend_generators.h"
27-
27+
#include "zend_weakrefs.h"
2828

2929
ZEND_API void zend_register_default_classes(void)
3030
{
@@ -33,4 +33,5 @@ ZEND_API void zend_register_default_classes(void)
3333
zend_register_iterator_wrapper();
3434
zend_register_closure_ce();
3535
zend_register_generator_ce();
36+
zend_register_weakref_ce();
3637
}

Zend/zend_execute_API.c

+5
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "zend_generators.h"
3434
#include "zend_vm.h"
3535
#include "zend_float.h"
36+
#include "zend_weakrefs.h"
3637
#ifdef HAVE_SYS_TIME_H
3738
#include <sys/time.h>
3839
#endif
@@ -181,6 +182,8 @@ void init_executor(void) /* {{{ */
181182
EG(persistent_functions_count) = EG(function_table)->nNumUsed;
182183
EG(persistent_classes_count) = EG(class_table)->nNumUsed;
183184

185+
zend_weakrefs_init();
186+
184187
EG(active) = 1;
185188
}
186189
/* }}} */
@@ -275,6 +278,8 @@ void shutdown_executor(void) /* {{{ */
275278

276279
zend_objects_store_free_object_storage(&EG(objects_store), fast_shutdown);
277280

281+
zend_weakrefs_shutdown();
282+
278283
/* All resources and objects are destroyed. */
279284
/* No PHP callback functions may be called after this point. */
280285
EG(active) = 0;

Zend/zend_globals.h

+2
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ struct _zend_executor_globals {
225225
zend_function trampoline;
226226
zend_op call_trampoline_op;
227227

228+
HashTable weakrefs;
229+
228230
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
229231
};
230232

Zend/zend_objects.c

+6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "zend_API.h"
2525
#include "zend_interfaces.h"
2626
#include "zend_exceptions.h"
27+
#include "zend_weakrefs.h"
2728

2829
static zend_always_inline void _zend_object_std_init(zend_object *object, zend_class_entry *ce)
2930
{
@@ -70,6 +71,7 @@ ZEND_API void zend_object_std_dtor(zend_object *object)
7071
p++;
7172
} while (p != end);
7273
}
74+
7375
if (UNEXPECTED(object->ce->ce_flags & ZEND_ACC_USE_GUARDS)) {
7476
if (EXPECTED(Z_TYPE_P(p) == IS_STRING)) {
7577
zval_ptr_dtor_str(p);
@@ -82,6 +84,10 @@ ZEND_API void zend_object_std_dtor(zend_object *object)
8284
FREE_HASHTABLE(guards);
8385
}
8486
}
87+
88+
if (UNEXPECTED(GC_FLAGS(object) & IS_OBJ_WEAKLY_REFERENCED)) {
89+
zend_weakrefs_notify(object);
90+
}
8591
}
8692

8793
ZEND_API void zend_objects_destroy_object(zend_object *object)

Zend/zend_types.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
585585
#define IS_ARRAY_PERSISTENT GC_PERSISTENT
586586

587587
/* object flags (zval.value->gc.u.flags) */
588+
#define IS_OBJ_WEAKLY_REFERENCED GC_PERSISTENT
588589
#define IS_OBJ_DESTRUCTOR_CALLED (1<<8)
589590
#define IS_OBJ_FREE_CALLED (1<<9)
590591

@@ -995,7 +996,7 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
995996
#if ZEND_RC_DEBUG
996997
extern ZEND_API zend_bool zend_rc_debug;
997998
# define ZEND_RC_MOD_CHECK(p) do { \
998-
if (zend_rc_debug) { \
999+
if (zend_rc_debug && zval_gc_type((p)->u.type_info) != IS_OBJECT) { \
9991000
ZEND_ASSERT(!(zval_gc_flags((p)->u.type_info) & GC_IMMUTABLE)); \
10001001
ZEND_ASSERT((zval_gc_flags((p)->u.type_info) & (GC_PERSISTENT|GC_PERSISTENT_LOCAL)) != GC_PERSISTENT); \
10011002
} \

0 commit comments

Comments
 (0)