@@ -1265,16 +1265,43 @@ static mut WP_MYSQL_NATIVE_AST_HANDLERS_PATCHED: bool = false;
12651265/// or change refcounts, so we deliberately do *not* call `set_object`
12661266/// (which addrefs); we set the union directly.
12671267unsafe extern "C" fn ast_get_gc (
1268- _object : * mut zend_object ,
1268+ object : * mut zend_object ,
12691269 table : * mut * mut zval ,
12701270 n : * mut std:: os:: raw:: c_int ,
12711271) -> * mut HashTable {
1272- // DEBUG: report no outgoing references at all. If this prevents the
1273- // PHPUnit segfault, the bug lives in the trace-zval construction
1274- // below; if the segfault persists, the bug is in installing the
1275- // handler itself (e.g., handlers struct in read-only memory).
12761272 * table = std:: ptr:: null_mut ( ) ;
12771273 * n = 0 ;
1274+
1275+ let Some ( ast) = ext_php_rs:: types:: ZendClassObject :: < WpMySqlNativeAst > :: from_zend_obj ( & * object)
1276+ . and_then ( |z| z. obj . as_ref ( ) )
1277+ else {
1278+ return std:: ptr:: null_mut ( ) ;
1279+ } ;
1280+
1281+ let Ok ( cache) = ast. node_cache . try_borrow ( ) else {
1282+ return std:: ptr:: null_mut ( ) ;
1283+ } ;
1284+ let Ok ( mut trace) = ast. gc_trace . try_borrow_mut ( ) else {
1285+ return std:: ptr:: null_mut ( ) ;
1286+ } ;
1287+
1288+ trace. clear ( ) ;
1289+ trace. reserve ( cache. len ( ) ) ;
1290+ for boxed in cache. values ( ) {
1291+ // Build a zval pointing at the cached wrapper without bumping
1292+ // refcount — the GC scan just enumerates outgoing references;
1293+ // mutating refcounts here would un-balance the collector's
1294+ // accounting. Using `Zval::new` + manual field writes (rather
1295+ // than `Zval::set_object` which would addref) keeps the trace
1296+ // entries refcount-neutral.
1297+ let mut zv: zval = std:: mem:: zeroed ( ) ;
1298+ zv. value . obj = ( & * * boxed) as * const ZendObject as * mut _ ;
1299+ zv. u1 . type_info = PHP_IS_OBJECT_EX ;
1300+ trace. push ( zv) ;
1301+ }
1302+
1303+ * table = trace. as_mut_ptr ( ) ;
1304+ * n = trace. len ( ) as std:: os:: raw:: c_int ;
12781305 std:: ptr:: null_mut ( )
12791306}
12801307
0 commit comments