21
21
#include "zend_closures.h"
22
22
#include "zend_partial.h"
23
23
24
- zend_object_handlers zend_partial_handlers ;
24
+ typedef struct _zend_partial {
25
+ zend_object std ;
26
+ zend_function prototype ;
27
+ zval This ;
28
+ zend_function func ;
29
+ zend_function trampoline ;
30
+ uint32_t argc ;
31
+ zval * argv ;
32
+ zend_array * named ;
33
+ } zend_partial ;
34
+
35
+ static zend_object_handlers zend_partial_handlers ;
25
36
26
37
#define ZEND_PARTIAL_PROPERTY_ERROR () \
27
38
zend_throw_error(NULL, "Partial closures cannot have properties")
28
39
29
- typedef struct _zend_partial_applied {
30
- zval This ;
31
- uint32_t argc ;
32
- zval * argv ;
33
- zend_array * named ;
34
- } zend_partial_applied ;
35
-
36
- typedef struct _zend_partial {
37
- zend_object std ;
38
- zend_function prototype ;
39
- zend_function func ;
40
- zend_function trampoline ;
41
- zend_partial_applied frame ;
42
- } zend_partial ;
43
-
44
40
static zend_always_inline zend_object * zend_partial_this (zend_object * object ) {
45
41
while (object && instanceof_function (object -> ce , zend_ce_closure )) {
46
42
zend_partial * ptr = (zend_partial * ) object ;
@@ -49,8 +45,8 @@ static zend_always_inline zend_object* zend_partial_this(zend_object *object) {
49
45
break ;
50
46
}
51
47
52
- if (Z_TYPE (ptr -> frame . This ) == IS_OBJECT ) {
53
- object = Z_OBJ (ptr -> frame . This );
48
+ if (Z_TYPE (ptr -> This ) == IS_OBJECT ) {
49
+ object = Z_OBJ (ptr -> This );
54
50
} else {
55
51
object = NULL ;
56
52
}
@@ -107,8 +103,8 @@ static zend_always_inline void zend_partial_prototype_u(zend_partial *partial, z
107
103
partial -> prototype .op_array .arg_info ++ ;
108
104
}
109
105
110
- zval * arg = partial -> frame . argv ,
111
- * aend = arg + partial -> frame . argc ;
106
+ zval * arg = partial -> argv ,
107
+ * aend = arg + partial -> argc ;
112
108
113
109
partial -> prototype .common .num_args = 0 ;
114
110
@@ -160,8 +156,8 @@ static zend_always_inline void zend_partial_prototype_i(zend_partial *partial, z
160
156
partial -> prototype .internal_function .arg_info ++ ;
161
157
}
162
158
163
- zval * arg = partial -> frame . argv ,
164
- * aend = arg + partial -> frame . argc ;
159
+ zval * arg = partial -> argv ,
160
+ * aend = arg + partial -> argc ;
165
161
166
162
partial -> prototype .common .num_args = 0 ;
167
163
@@ -222,8 +218,8 @@ static zend_always_inline zend_object* zend_partial_new(zend_class_entry *type)
222
218
}
223
219
224
220
static zend_always_inline void zend_partial_debug_i (zend_partial * partial , HashTable * ht ) {
225
- zval * arg = partial -> frame . argv ,
226
- * aend = arg + partial -> frame . argc ;
221
+ zval * arg = partial -> argv ,
222
+ * aend = arg + partial -> argc ;
227
223
zend_internal_arg_info * info = partial -> func .internal_function .arg_info ,
228
224
* iend = info + partial -> func .internal_function .num_args ;
229
225
@@ -254,8 +250,8 @@ static zend_always_inline void zend_partial_debug_i(zend_partial *partial, HashT
254
250
}
255
251
256
252
static zend_always_inline void zend_partial_debug_u (zend_partial * partial , HashTable * ht ) {
257
- zval * arg = partial -> frame . argv ,
258
- * aend = arg + partial -> frame . argc ;
253
+ zval * arg = partial -> argv ,
254
+ * aend = arg + partial -> argc ;
259
255
zend_arg_info * info = partial -> func .op_array .arg_info ,
260
256
* iend = info + partial -> func .op_array .num_args ;
261
257
@@ -290,9 +286,7 @@ static HashTable *zend_partial_debug(zend_object *object, int *is_temp) {
290
286
zval args ;
291
287
HashTable * ht ;
292
288
293
- * is_temp = 1 ;
294
-
295
- ht = zend_new_array (1 );
289
+ ht = zend_closure_get_debug_info (object , is_temp );
296
290
297
291
array_init (& args );
298
292
zend_hash_update (ht , ZSTR_KNOWN (ZEND_STR_ARGS ), & args );
@@ -341,8 +335,8 @@ static HashTable *zend_partial_get_gc(zend_object *obj, zval **table, int *n)
341
335
{
342
336
zend_partial * partial = (zend_partial * )obj ;
343
337
344
- * table = Z_TYPE (partial -> frame . This ) != IS_NULL ? & partial -> frame . This : NULL ;
345
- * n = Z_TYPE (partial -> frame . This ) != IS_NULL ? 1 : 0 ;
338
+ * table = Z_TYPE (partial -> This ) != IS_NULL ? & partial -> This : NULL ;
339
+ * n = Z_TYPE (partial -> This ) != IS_NULL ? 1 : 0 ;
346
340
347
341
return (partial -> func .type == ZEND_USER_FUNCTION ) ?
348
342
ZEND_MAP_PTR_GET (partial -> func .op_array .static_variables_ptr ) : NULL ;
@@ -378,8 +372,8 @@ static int zend_partial_get_trampoline(zend_object *obj, zend_class_entry **ce_p
378
372
static void zend_partial_free (zend_object * object ) {
379
373
zend_partial * partial = (zend_partial * ) object ;
380
374
381
- zval * arg = partial -> frame . argv ,
382
- * end = arg + partial -> frame . argc ;
375
+ zval * arg = partial -> argv ,
376
+ * end = arg + partial -> argc ;
383
377
384
378
while (arg < end ) {
385
379
if (Z_OPT_REFCOUNTED_P (arg )) {
@@ -388,10 +382,10 @@ static void zend_partial_free(zend_object *object) {
388
382
arg ++ ;
389
383
}
390
384
391
- efree_size (partial -> frame . argv , sizeof (zval ) * partial -> frame . argc );
385
+ efree_size (partial -> argv , sizeof (zval ) * partial -> argc );
392
386
393
- if (partial -> frame . named ) {
394
- zend_array_release (partial -> frame . named );
387
+ if (partial -> named ) {
388
+ zend_array_release (partial -> named );
395
389
}
396
390
397
391
zend_arg_info * info = partial -> prototype .common .arg_info ;
@@ -406,7 +400,7 @@ static void zend_partial_free(zend_object *object) {
406
400
destroy_zend_function (& partial -> func );
407
401
}
408
402
409
- zval_ptr_dtor (& partial -> frame . This );
403
+ zval_ptr_dtor (& partial -> This );
410
404
411
405
zend_object_std_dtor (object );
412
406
}
@@ -442,17 +436,17 @@ ZEND_NAMED_FUNCTION(zend_partial_call_magic)
442
436
443
437
fci .size = sizeof (zend_fcall_info );
444
438
fci .retval = return_value ;
445
- fci .param_count = MAX (partial -> func .common .num_args , partial -> frame . argc + num_params );
439
+ fci .param_count = MAX (partial -> func .common .num_args , partial -> argc + num_params );
446
440
fci .params = ecalloc (sizeof (zval ), fci .param_count );
447
441
fcc .function_handler = & partial -> func ;
448
442
449
- if (!Z_ISUNDEF (partial -> frame . This )) {
443
+ if (!Z_ISUNDEF (partial -> This )) {
450
444
fci .object =
451
445
fcc .object =
452
- zend_partial_this (Z_OBJ (partial -> frame . This ));
446
+ zend_partial_this (Z_OBJ (partial -> This ));
453
447
}
454
448
455
- memcpy (fci .params , partial -> frame . argv , partial -> frame . argc * sizeof (zval ));
449
+ memcpy (fci .params , partial -> argv , partial -> argc * sizeof (zval ));
456
450
457
451
zval * arg = fci .params ,
458
452
* aend = arg + fci .param_count ,
@@ -471,14 +465,14 @@ ZEND_NAMED_FUNCTION(zend_partial_call_magic)
471
465
arg ++ ;
472
466
}
473
467
474
- if (partial -> frame . named ) {
468
+ if (partial -> named ) {
475
469
if (!named_args ) {
476
470
named_args =
477
- partial -> frame . named ;
471
+ partial -> named ;
478
472
GC_ADDREF (named_args );
479
473
} else {
480
474
HashTable * nested =
481
- zend_array_dup (partial -> frame . named );
475
+ zend_array_dup (partial -> named );
482
476
483
477
zend_hash_merge (
484
478
nested ,
@@ -500,7 +494,7 @@ ZEND_NAMED_FUNCTION(zend_partial_call_magic)
500
494
}
501
495
}
502
496
503
- if (partial -> frame . named ) {
497
+ if (partial -> named ) {
504
498
zend_array_release (named_args );
505
499
}
506
500
@@ -510,7 +504,7 @@ ZEND_NAMED_FUNCTION(zend_partial_call_magic)
510
504
zval_ptr_dtor (return_value );
511
505
512
506
RETVAL_OBJ (
513
- Z_OBJ (partial -> frame . This ));
507
+ Z_OBJ (partial -> This ));
514
508
}
515
509
516
510
if (!fcc .function_handler ) {
@@ -531,61 +525,59 @@ void zend_partial_apply(zval *result, zend_execute_data *call) {
531
525
if ((parent = zend_partial_parent (& call -> This ))) {
532
526
function = & parent -> func ;
533
527
prototype = & parent -> prototype ;
534
-
535
- zend_partial_applied * frame = & parent -> frame ;
536
528
537
- partial -> frame . argc = frame -> argc + ZEND_CALL_NUM_ARGS (call );
538
- partial -> frame . argv = ecalloc (partial -> frame . argc , sizeof (zval ));
529
+ partial -> argc = parent -> argc + ZEND_CALL_NUM_ARGS (call );
530
+ partial -> argv = ecalloc (partial -> argc , sizeof (zval ));
539
531
540
- memcpy (partial -> frame . argv ,
541
- frame -> argv , frame -> argc * sizeof (zval ));
532
+ memcpy (partial -> argv ,
533
+ parent -> argv , parent -> argc * sizeof (zval ));
542
534
543
535
uint32_t arg = 0 ,
544
- aend = frame -> argc ;
536
+ aend = parent -> argc ;
545
537
zval * param = ZEND_CALL_ARG (call , 1 ),
546
538
* pend = param + ZEND_CALL_NUM_ARGS (call );
547
539
548
540
while (arg < aend && param < pend ) {
549
- if (Z_TYPE (partial -> frame . argv [arg ]) == IS_UNDEF ) {
541
+ if (Z_TYPE (partial -> argv [arg ]) == IS_UNDEF ) {
550
542
if (!Z_ISUNDEF_P (param )) {
551
543
ZVAL_COPY_VALUE (
552
- & partial -> frame . argv [arg ], param );
544
+ & partial -> argv [arg ], param );
553
545
}
554
546
param ++ ;
555
547
}
556
548
arg ++ ;
557
549
}
558
550
559
551
if ((ZEND_CALL_INFO (call ) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS )) {
560
- if (frame -> named ) {
561
- partial -> frame . named = zend_array_dup (frame -> named );
552
+ if (parent -> named ) {
553
+ partial -> named = zend_array_dup (parent -> named );
562
554
563
555
zend_hash_merge (
564
- partial -> frame . named ,
556
+ partial -> named ,
565
557
call -> extra_named_params , zval_copy_ctor , true);
566
558
} else {
567
- partial -> frame . named =
559
+ partial -> named =
568
560
call -> extra_named_params ;
569
561
GC_ADDREF (call -> extra_named_params );
570
562
}
571
563
}
572
564
} else {
573
565
function = call -> func ;
574
566
575
- partial -> frame . argc = ZEND_CALL_NUM_ARGS (call );
576
- partial -> frame . argv = ecalloc (partial -> frame . argc , sizeof (zval ));
567
+ partial -> argc = ZEND_CALL_NUM_ARGS (call );
568
+ partial -> argv = ecalloc (partial -> argc , sizeof (zval ));
577
569
578
- memcpy (partial -> frame . argv ,
579
- ZEND_CALL_ARG (call , 1 ), partial -> frame . argc * sizeof (zval ));
570
+ memcpy (partial -> argv ,
571
+ ZEND_CALL_ARG (call , 1 ), partial -> argc * sizeof (zval ));
580
572
581
573
if ((ZEND_CALL_INFO (call ) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS )) {
582
- partial -> frame . named =
574
+ partial -> named =
583
575
call -> extra_named_params ;
584
576
GC_ADDREF (call -> extra_named_params );
585
577
}
586
578
}
587
579
588
- ZVAL_COPY (& partial -> frame . This , & call -> This );
580
+ ZVAL_COPY (& partial -> This , & call -> This );
589
581
590
582
memcpy (& partial -> func , function ,
591
583
function -> type == ZEND_INTERNAL_FUNCTION ?
@@ -601,7 +593,7 @@ void zend_partial_apply(zval *result, zend_execute_data *call) {
601
593
602
594
if (partial -> func .common .fn_flags & ZEND_ACC_CTOR ) {
603
595
GC_ADD_FLAGS (
604
- Z_OBJ (partial -> frame . This ), IS_OBJ_DESTRUCTOR_CALLED );
596
+ Z_OBJ (partial -> This ), IS_OBJ_DESTRUCTOR_CALLED );
605
597
}
606
598
607
599
if (partial -> func .type == ZEND_USER_FUNCTION ) {
0 commit comments