@@ -6504,7 +6504,7 @@ ZEND_METHOD(ReflectionAttribute, getArguments)
65046504}
65056505/* }}} */
65066506
6507- static int call_attribute_constructor (zend_class_entry * ce , zend_object * obj , zval * args , uint32_t argc ) /* {{{ */
6507+ static int call_attribute_constructor (zend_class_entry * ce , zend_object * obj , zval * args , uint32_t argc , HashTable * named_params ) /* {{{ */
65086508{
65096509 zend_function * ctor = ce -> constructor ;
65106510 ZEND_ASSERT (ctor != NULL );
@@ -6514,7 +6514,27 @@ static int call_attribute_constructor(zend_class_entry *ce, zend_object *obj, zv
65146514 return FAILURE ;
65156515 }
65166516
6517- zend_call_known_instance_method (ctor , obj , NULL , argc , args );
6517+ {
6518+ zval retval ;
6519+ zend_fcall_info_named fci_named ;
6520+ zend_fcall_info_cache fcic ;
6521+
6522+ fci_named .fci .size = sizeof (zend_fcall_info_named );
6523+ fci_named .fci .object = obj ;
6524+ fci_named .fci .retval = & retval ;
6525+ fci_named .fci .param_count = argc ;
6526+ fci_named .fci .params = args ;
6527+ fci_named .fci .no_separation = 1 ;
6528+ fci_named .named_params = named_params ;
6529+ ZVAL_UNDEF (& fci_named .fci .function_name ); /* Unused */
6530+
6531+ fcic .function_handler = ctor ;
6532+ fcic .object = obj ;
6533+ fcic .called_scope = obj -> ce ;
6534+
6535+ zend_call_function (& fci_named .fci , & fcic );
6536+ }
6537+
65186538 if (EG (exception )) {
65196539 zend_object_store_ctor_failed (obj );
65206540 return FAILURE ;
@@ -6524,7 +6544,8 @@ static int call_attribute_constructor(zend_class_entry *ce, zend_object *obj, zv
65246544}
65256545/* }}} */
65266546
6527- static void attribute_ctor_cleanup (zval * obj , zval * args , uint32_t argc ) /* {{{ */
6547+ static void attribute_ctor_cleanup (
6548+ zval * obj , zval * args , uint32_t argc , HashTable * named_params ) /* {{{ */
65286549{
65296550 if (obj ) {
65306551 zval_ptr_dtor (obj );
@@ -6539,6 +6560,10 @@ static void attribute_ctor_cleanup(zval *obj, zval *args, uint32_t argc) /* {{{
65396560
65406561 efree (args );
65416562 }
6563+
6564+ if (named_params ) {
6565+ zend_array_destroy (named_params );
6566+ }
65426567}
65436568/* }}} */
65446569
@@ -6554,8 +6579,7 @@ ZEND_METHOD(ReflectionAttribute, newInstance)
65546579 zval obj ;
65556580
65566581 zval * args = NULL ;
6557- uint32_t count ;
6558- uint32_t argc = 0 ;
6582+ HashTable * named_params = NULL ;
65596583
65606584 if (zend_parse_parameters_none () == FAILURE ) {
65616585 RETURN_THROWS ();
@@ -6612,31 +6636,40 @@ ZEND_METHOD(ReflectionAttribute, newInstance)
66126636 RETURN_THROWS ();
66136637 }
66146638
6615- count = attr -> data -> argc ;
6616-
6617- if (count ) {
6618- args = emalloc (count * sizeof (zval ));
6639+ uint32_t argc = 0 ;
6640+ if (attr -> data -> argc ) {
6641+ args = emalloc (attr -> data -> argc * sizeof (zval ));
66196642
6620- for (argc = 0 ; argc < attr -> data -> argc ; argc ++ ) {
6621- if (FAILURE == zend_get_attribute_value (& args [argc ], attr -> data , argc , attr -> scope )) {
6622- attribute_ctor_cleanup (& obj , args , argc );
6643+ for (uint32_t i = 0 ; i < attr -> data -> argc ; i ++ ) {
6644+ zval val ;
6645+ if (FAILURE == zend_get_attribute_value (& val , attr -> data , i , attr -> scope )) {
6646+ attribute_ctor_cleanup (& obj , args , i , named_params );
66236647 RETURN_THROWS ();
66246648 }
6649+ if (attr -> data -> args [i ].name ) {
6650+ if (!named_params ) {
6651+ named_params = zend_new_array (0 );
6652+ }
6653+ zend_hash_add_new (named_params , attr -> data -> args [i ].name , & val );
6654+ } else {
6655+ ZVAL_COPY_VALUE (& args [i ], & val );
6656+ argc ++ ;
6657+ }
66256658 }
66266659 }
66276660
66286661 if (ce -> constructor ) {
6629- if (FAILURE == call_attribute_constructor (ce , Z_OBJ (obj ), args , argc )) {
6630- attribute_ctor_cleanup (& obj , args , argc );
6662+ if (FAILURE == call_attribute_constructor (ce , Z_OBJ (obj ), args , argc , named_params )) {
6663+ attribute_ctor_cleanup (& obj , args , argc , named_params );
66316664 RETURN_THROWS ();
66326665 }
6633- } else if (argc ) {
6634- attribute_ctor_cleanup (& obj , args , argc );
6666+ } else if (argc || named_params ) {
6667+ attribute_ctor_cleanup (& obj , args , argc , named_params );
66356668 zend_throw_error (NULL , "Attribute class '%s' does not have a constructor, cannot pass arguments" , ZSTR_VAL (ce -> name ));
66366669 RETURN_THROWS ();
66376670 }
66386671
6639- attribute_ctor_cleanup (NULL , args , argc );
6672+ attribute_ctor_cleanup (NULL , args , argc , named_params );
66406673
66416674 RETURN_COPY_VALUE (& obj );
66426675}
0 commit comments