@@ -1467,20 +1467,41 @@ static void reflection_type_factory(
1467
1467
}
1468
1468
}
1469
1469
1470
- /* {{{ reflection_function_factory */
1471
- static void reflection_function_factory (zend_function * function , zval * closure_object , zval * object )
1470
+ /* copy of hidden zend_closure */
1471
+ typedef struct _zend_closure {
1472
+ zend_object std ;
1473
+ zend_function func ;
1474
+ zval this_ptr ;
1475
+ zend_class_entry * called_scope ;
1476
+ zif_handler orig_internal_handler ;
1477
+ } zend_closure ;
1478
+
1479
+ static void reflection_function_create_common (zend_function * function , zend_object * closure_object , zval * object )
1472
1480
{
1473
- reflection_object * intern ;
1474
- reflection_instantiate (reflection_function_ptr , object );
1475
- intern = Z_REFLECTION_P (object );
1481
+ reflection_object * intern = Z_REFLECTION_P (object );
1482
+
1476
1483
intern -> ptr = function ;
1477
1484
intern -> ref_type = REF_TYPE_FUNCTION ;
1478
1485
intern -> ce = NULL ;
1479
1486
if (closure_object ) {
1480
- ZVAL_OBJ_COPY (& intern -> obj , Z_OBJ_P (closure_object ));
1487
+ ZVAL_OBJ_COPY (& intern -> obj , closure_object );
1488
+ zend_closure * closure = (zend_closure * ) closure_object ;
1489
+ /* if it is bound to a class, resolve to it */
1490
+ if (closure -> called_scope ) {
1491
+ intern -> ce = closure -> called_scope ;
1492
+ }
1493
+ } else {
1494
+ ZVAL_UNDEF (& intern -> obj );
1481
1495
}
1482
1496
ZVAL_STR_COPY (reflection_prop_name (object ), function -> common .function_name );
1483
1497
}
1498
+
1499
+ /* {{{ reflection_function_factory */
1500
+ static void reflection_function_factory (zend_function * function , zend_object * closure_object , zval * object )
1501
+ {
1502
+ reflection_instantiate (reflection_function_ptr , object );
1503
+ reflection_function_create_common (function , closure_object , object );
1504
+ }
1484
1505
/* }}} */
1485
1506
1486
1507
/* {{{ reflection_method_factory */
@@ -1632,27 +1653,18 @@ ZEND_METHOD(Reflection, getModifierNames)
1632
1653
/* {{{ Constructor. Throws an Exception in case the given function does not exist */
1633
1654
ZEND_METHOD (ReflectionFunction , __construct )
1634
1655
{
1635
- zval * object ;
1636
1656
zend_object * closure_obj = NULL ;
1637
- reflection_object * intern ;
1657
+ zend_string * fname = NULL ;
1638
1658
zend_function * fptr ;
1639
- zend_string * fname , * lcname ;
1640
-
1641
- object = ZEND_THIS ;
1642
- intern = Z_REFLECTION_P (object );
1643
1659
1644
1660
ZEND_PARSE_PARAMETERS_START (1 , 1 )
1645
1661
Z_PARAM_OBJ_OF_CLASS_OR_STR (closure_obj , zend_ce_closure , fname )
1646
1662
ZEND_PARSE_PARAMETERS_END ();
1647
1663
1648
- /* Set CE to NULL */
1649
- intern -> ce = NULL ;
1650
1664
if (closure_obj ) {
1651
1665
fptr = (zend_function * )zend_get_closure_method_def (closure_obj );
1652
- //zend_object *tmp = NULL;
1653
- ///* We use the get_closure object handler that always succeds to fetch the function and CE pointers */
1654
- //closure_obj->handlers->get_closure(closure_obj, &intern->ce, &fptr, /* obj_ptr */ &tmp, /* check_only */ false);
1655
1666
} else {
1667
+ zend_string * lcname ;
1656
1668
if (UNEXPECTED (ZSTR_VAL (fname )[0 ] == '\\' )) {
1657
1669
/* Ignore leading "\" */
1658
1670
ALLOCA_FLAG (use_heap )
@@ -1673,19 +1685,15 @@ ZEND_METHOD(ReflectionFunction, __construct)
1673
1685
}
1674
1686
}
1675
1687
1676
- if (intern -> ptr ) {
1677
- zval_ptr_dtor (& intern -> obj );
1678
- zval_ptr_dtor (reflection_prop_name (object ));
1679
- }
1688
+ // TODO How can this ever be hit?
1689
+ //zval *object = ZEND_THIS;
1690
+ //reflection_object *intern = Z_REFLECTION_P(object);
1691
+ //if (intern->ptr) {
1692
+ // zval_ptr_dtor(&intern->obj);
1693
+ // zval_ptr_dtor(reflection_prop_name(object));
1694
+ //}
1680
1695
1681
- ZVAL_STR_COPY (reflection_prop_name (object ), fptr -> common .function_name );
1682
- intern -> ptr = fptr ;
1683
- intern -> ref_type = REF_TYPE_FUNCTION ;
1684
- if (closure_obj ) {
1685
- ZVAL_OBJ_COPY (& intern -> obj , closure_obj );
1686
- } else {
1687
- ZVAL_UNDEF (& intern -> obj );
1688
- }
1696
+ reflection_function_create_common (fptr , closure_obj , ZEND_THIS );
1689
1697
}
1690
1698
/* }}} */
1691
1699
@@ -2389,9 +2397,7 @@ ZEND_METHOD(ReflectionGenerator, getFunction)
2389
2397
REFLECTION_CHECK_VALID_GENERATOR (ex )
2390
2398
2391
2399
if (ex -> func -> common .fn_flags & ZEND_ACC_CLOSURE ) {
2392
- zval closure ;
2393
- ZVAL_OBJ (& closure , ZEND_CLOSURE_OBJECT (ex -> func ));
2394
- reflection_function_factory (ex -> func , & closure , return_value );
2400
+ reflection_function_factory (ex -> func , ZEND_CLOSURE_OBJECT (ex -> func ), return_value );
2395
2401
} else if (ex -> func -> op_array .scope ) {
2396
2402
reflection_method_factory (ex -> func -> op_array .scope , ex -> func , NULL , return_value );
2397
2403
} else {
@@ -2674,7 +2680,7 @@ ZEND_METHOD(ReflectionParameter, getDeclaringFunction)
2674
2680
GET_REFLECTION_OBJECT_PTR (param );
2675
2681
2676
2682
if (!param -> fptr -> common .scope ) {
2677
- reflection_function_factory (_copy_function (param -> fptr ), Z_ISUNDEF (intern -> obj )? NULL : & intern -> obj , return_value );
2683
+ reflection_function_factory (_copy_function (param -> fptr ), Z_ISUNDEF (intern -> obj )? NULL : Z_OBJ ( intern -> obj ) , return_value );
2678
2684
} else {
2679
2685
reflection_method_factory (param -> fptr -> common .scope , _copy_function (param -> fptr ), Z_ISUNDEF (intern -> obj )? NULL : & intern -> obj , return_value );
2680
2686
}
@@ -3159,7 +3165,7 @@ ZEND_METHOD(ReflectionNamedType, isBuiltin)
3159
3165
}
3160
3166
/* }}} */
3161
3167
3162
- /* {{{ Returns whether type is a builtin type */
3168
+ /* {{{ Resolve a relative class type to a proper named type */
3163
3169
ZEND_METHOD (ReflectionRelativeClassType , resolveToNamedType )
3164
3170
{
3165
3171
reflection_object * intern ;
@@ -3195,9 +3201,19 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
3195
3201
}
3196
3202
resolved_type = (zend_type ) ZEND_TYPE_INIT_CLASS (intern -> ce -> name , allows_null , /* extra flags */ 0 );
3197
3203
} else {
3198
- ZEND_ASSERT (zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "self" ) || zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "parent" ));
3199
3204
ZEND_ASSERT (ZEND_TYPE_HAS_NAME (param -> type ));
3200
- resolved_type = (zend_type ) ZEND_TYPE_INIT_CLASS (ZEND_TYPE_NAME (param -> type ), allows_null , /* extra flags */ 0 );
3205
+ ZEND_ASSERT (zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "self" ) || zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "parent" ));
3206
+
3207
+ if (zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "self" )) {
3208
+ resolved_type = (zend_type ) ZEND_TYPE_INIT_CLASS (intern -> ce -> name , allows_null , /* extra flags */ 0 );
3209
+ } else {
3210
+ if (!intern -> ce -> parent ) {
3211
+ zend_throw_exception_ex (reflection_exception_ptr , 0 ,
3212
+ "Cannot resolve \"parent\" type when class has no parent" );
3213
+ RETURN_THROWS ();
3214
+ }
3215
+ resolved_type = (zend_type ) ZEND_TYPE_INIT_CLASS (intern -> ce -> parent -> name , allows_null , /* extra flags */ 0 );
3216
+ }
3201
3217
}
3202
3218
3203
3219
reflection_type_factory (resolved_type , return_value , /* legacy_behavior */ true, intern -> ce );
0 commit comments