Hi Nathan, Bin,

bin.cheng <bin.ch...@linux.alibaba.com> wrote:

> On Mon, Jan 20, 2020 at 10:59 PM Iain Sandoe <i...@sandoe.co.uk> wrote:
>> Hi Bin,
>> 
>> bin.cheng <bin.ch...@linux.alibaba.com> wrote:
>> 
>>> By standard, coroutine body should be encapsulated in try-catch block
>>> as following:
>>>  try {
>>>    // coroutine body
>>>  } catch(...) {
>>>    promise.unhandled_exception();
>>>  }
>>> Given above try-catch block is implemented in the coroutine actor
>>> function called by coroutine ramp function, so the promise should
>>> be accessed via actor function's coroutine frame pointer argument,
>>> rather than the ramp function's coroutine frame variable.
>> 
>> thanks, good catch!
>> it has not triggered for me (including on some more complex test-cases that 
>> are not useable
>> in the testsuite).
>> 
>>> This patch also refactored code to make the fix easy, unfortunately,
>> 
>> see below,
>> 
>>> I failed to reduce a test case from cpproro.
>> 
>> it would be good if we could try to find a reproducer.  I’m happy to try and 
>> throw
>> creduce at a preprocessed file, if you have one.
>> 
>>> gcc/cp
>>> 2020-01-20  Bin Cheng  <bin.li...@linux.alibaba.com>
>>> 
>>>        * coroutines.cc (act_des_fn, wrap_coroutine_body): New.
>>>        (morph_fn_to_coro): Call act_des_fn to build actor/destroy decls, as
>>>        well as access promise via actor function's frame pointer argument.
>>>        Refactor code into above functions.
>>>        (build_actor_fn, build_destroy_fn): Use frame pointer argument
>> +      /* We still try to look for the promise method and warn if it's not
>> +        present.  */
>> +      tree ueh_meth
>> +       = lookup_promise_method (orig, coro_unhandled_exception_identifier,
>> +                                loc, /*musthave=*/ false);
>> +      if (!ueh_meth || ueh_meth == error_mark_node)
>> +       warning_at (loc, 0, "no member named %qE in %qT",
>> +                   coro_unhandled_exception_identifier,
>> +                   get_coroutine_promise_type (orig));
>> +    }
>> +  /* Else we don't check and don't care if the method is missing.  */
>> +
>> +  return fnbody;
>> +}
>> 
>> IMO this ^^^ obfuscates the fix, and I don’t think it should be done at the 
>> same time.
> Sure, given we are in this stage, I split the patch and leave refactoring to 
> future.

Thank you, this is easier to see.

>  IMHO, the function is too long so self-contained operations worth outlined 
> function even it's called once.

There are two changes “in the pipeline” that might make an alternate split 
better:
1) There is a change to wrap the await_resume() for initial suspend in a 
try-catch, this probably means
   that it would be better to partition the code that looks up 
unhandled_exception (), since that would then
  probably be used twice.

2) There is on-going discussion about how to guarantee tail-calling in 
symmetric transfers.  At present,
   ISTM that this will need a second wrapper around the whole resume() function.

I would prefer to leave any refactoring until these two things are clarified, 
does that make sense?

----

Nathan, is this OK for trunk as-is?
thanks
Iain

> Patch updated as attached.
> 
> Thanks,
> bin
> 
> gcc/cp
> 2020-01-20  Bin Cheng  <bin.li...@linux.alibaba.com>
>         * coroutines.cc (act_des_fn): New.
>         (morph_fn_to_coro): Call act_des_fn to build actor/destroy decls.
>         Access promise via actor function's frame pointer argument.
>         (build_actor_fn, build_destroy_fn): Use frame pointer argument.

Attachment: 0001-Use-promise-in-coroutine-frame-in-actor-function.patch
Description: Binary data


Reply via email to