@@ -182,40 +182,80 @@ static void prepare_class_function_table(const pmmpthread_ident_t* source, zend_
182
182
} ZEND_HASH_FOREACH_END ();
183
183
} /* }}} */
184
184
185
- /* {{{ */
186
- static void prepare_class_property_table (const pmmpthread_ident_t * source , zend_class_entry * candidate , zend_class_entry * prepared ) {
185
+ static zend_property_info * copy_property_info (
186
+ const pmmpthread_ident_t * source ,
187
+ const zend_class_entry * candidate ,
188
+ zend_class_entry * prepared ,
189
+ const zend_property_info * info
190
+ ) {
191
+ zend_property_info * dup = zend_hash_index_find_ptr (& PMMPTHREAD_ZG (resolve ), (zend_ulong )info );
192
+ if (dup ) {
193
+ return dup ;
194
+ }
187
195
188
- zend_property_info * info ;
189
- zend_string * name ;
190
- ZEND_HASH_FOREACH_STR_KEY_PTR (& candidate -> properties_info , name , info ) {
191
- zend_property_info * dup ;
196
+ if (info -> ce -> type == ZEND_INTERNAL_CLASS ) {
197
+ dup = pemalloc (sizeof (zend_property_info ), 1 );
198
+ }
199
+ else {
200
+ dup = zend_arena_alloc (& CG (arena ), sizeof (zend_property_info ));
201
+ }
202
+ memcpy (dup , info , sizeof (zend_property_info ));
192
203
193
- if (info -> ce -> type == ZEND_INTERNAL_CLASS ) {
194
- dup = pemalloc (sizeof (zend_property_info ), 1 );
195
- } else {
196
- dup = zend_arena_alloc (& CG (arena ), sizeof (zend_property_info ));
197
- }
198
- memcpy (dup , info , sizeof (zend_property_info ));
204
+ zend_hash_index_update_ptr (& PMMPTHREAD_ZG (resolve ), (zend_ulong )info , dup );
199
205
200
- dup -> name = pmmpthread_copy_string (info -> name );
201
- if (info -> doc_comment ) {
202
- if (PMMPTHREAD_ZG (options ) & PMMPTHREAD_INHERIT_COMMENTS ) {
203
- dup -> doc_comment = pmmpthread_copy_string (info -> doc_comment );
204
- } else dup -> doc_comment = NULL ;
206
+ dup -> name = pmmpthread_copy_string (info -> name );
207
+ if (info -> doc_comment ) {
208
+ if (PMMPTHREAD_ZG (options ) & PMMPTHREAD_INHERIT_COMMENTS ) {
209
+ dup -> doc_comment = pmmpthread_copy_string (info -> doc_comment );
205
210
}
211
+ else dup -> doc_comment = NULL ;
212
+ }
206
213
207
- if (info -> ce ) {
208
- if (info -> ce == candidate ) {
209
- dup -> ce = prepared ;
210
- } else dup -> ce = pmmpthread_prepared_entry (source , info -> ce );
214
+ if (info -> ce ) {
215
+ if (info -> ce == candidate ) {
216
+ dup -> ce = prepared ;
211
217
}
218
+ else dup -> ce = pmmpthread_prepared_entry (source , info -> ce );
219
+ }
220
+
221
+ pmmpthread_copy_zend_type (& info -> type , & dup -> type );
212
222
213
- pmmpthread_copy_zend_type (& info -> type , & dup -> type );
223
+ if (info -> attributes ) {
224
+ dup -> attributes = pmmpthread_copy_attributes (source , info -> attributes , info -> ce -> type == ZEND_INTERNAL_CLASS ? NULL : info -> ce -> info .user .filename );
225
+ }
214
226
215
- if (info -> attributes ) {
216
- dup -> attributes = pmmpthread_copy_attributes (source , info -> attributes , info -> ce -> type == ZEND_INTERNAL_CLASS ? NULL : info -> ce -> info .user .filename );
227
+ #if PHP_VERSION_ID >= 80400
228
+ if (info -> prototype ) {
229
+ dup -> prototype = copy_property_info (source , candidate , prepared , info -> prototype );
230
+ } else dup -> prototype = NULL ;
231
+
232
+ if (info -> hooks ) {
233
+ dup -> hooks = zend_arena_alloc (& CG (arena ), ZEND_PROPERTY_HOOK_STRUCT_SIZE );
234
+ for (uint32_t i = 0 ; i < ZEND_PROPERTY_HOOK_COUNT ; i ++ ) {
235
+ if (info -> hooks [i ]) {
236
+ const zend_function * original_hook = info -> hooks [i ];
237
+ zend_function * copy_hook = pmmpthread_copy_function (source , original_hook );
238
+
239
+ if (original_hook -> type == ZEND_USER_FUNCTION ) {
240
+ ZEND_ASSERT (original_hook -> op_array .prop_info );
241
+ copy_hook -> op_array .prop_info = copy_property_info (source , candidate , prepared , info -> hooks [i ]-> op_array .prop_info );
242
+ }
243
+
244
+ dup -> hooks [i ] = copy_hook ;
245
+ } else dup -> hooks [i ] = NULL ;
217
246
}
247
+ } else dup -> hooks = NULL ;
248
+ #endif
218
249
250
+ return dup ;
251
+ }
252
+ /* {{{ */
253
+ static void prepare_class_property_table (const pmmpthread_ident_t * source , zend_class_entry * candidate , zend_class_entry * prepared ) {
254
+
255
+ zend_property_info * info ;
256
+ zend_string * name ;
257
+ ZEND_HASH_FOREACH_STR_KEY_PTR (& candidate -> properties_info , name , info ) {
258
+ zend_property_info * dup = copy_property_info (source , candidate , prepared , info );
219
259
if (!zend_hash_str_add_ptr (& prepared -> properties_info , name -> val , name -> len , dup )) {
220
260
if (dup -> doc_comment )
221
261
zend_string_release (dup -> doc_comment );
@@ -257,7 +297,11 @@ static void prepare_class_property_table(const pmmpthread_ident_t* source, zend_
257
297
}
258
298
259
299
ZEND_HASH_FOREACH_PTR (& prepared -> properties_info , info ) {
260
- if (info -> ce == prepared && (info -> flags & ZEND_ACC_STATIC ) == 0 ) {
300
+ if (info -> ce == prepared && (info -> flags & ZEND_ACC_STATIC ) == 0
301
+ #if PHP_VERSION_ID >= 80400
302
+ && (info -> flags & ZEND_ACC_VIRTUAL ) == 0
303
+ #endif
304
+ ) {
261
305
prepared -> properties_info_table [OBJ_PROP_TO_NUM (info -> offset )] = info ;
262
306
}
263
307
} ZEND_HASH_FOREACH_END ();
@@ -484,6 +528,8 @@ static zend_class_entry* pmmpthread_copy_entry(const pmmpthread_ident_t* source,
484
528
(candidate -> doc_comment )) {
485
529
prepared -> doc_comment = pmmpthread_copy_string (candidate -> doc_comment );
486
530
} else prepared -> doc_comment = NULL ;
531
+ prepared -> num_hooked_props = candidate -> num_hooked_props ;
532
+ prepared -> num_hooked_prop_variance_checks = candidate -> num_hooked_prop_variance_checks ;
487
533
#else
488
534
(candidate -> info .user .doc_comment )) {
489
535
prepared -> info .user .doc_comment = pmmpthread_copy_string (candidate -> info .user .doc_comment );
0 commit comments