@@ -1590,6 +1590,7 @@ static SgObject throw_delimited_continuation_body(SgObject,
15901590 SgContinuation * ,
15911591 SgObject ,
15921592 SgPrompt * );
1593+ static SgObject throw_continuation_end (SgVM * , SgObject );
15931594
15941595static SgObject throw_continuation_body (SgObject handlers ,
15951596 SgContinuation * c ,
@@ -1643,31 +1644,36 @@ static SgObject throw_continuation_body(SgObject handlers,
16431644 vm -> cont = c -> cont ;
16441645 vm -> dynamicWinders = c -> winders ;
16451646 }
1646- vm -> pc = return_code ;
1647- /* store arguments of the continuation to ac */
1648- if ( SG_NULLP ( args )) { /* no value */
1649- /* does this happen? */
1650- vm -> ac = SG_UNDEF ;
1651- vm -> valuesCount = 0 ;
1652- } else if ( SG_NULLP ( SG_CDR ( args ))) { /* usual case */
1653- vm -> ac = SG_CAR ( args );
1654- vm -> valuesCount = 1 ;
1655- } else { /* multi values */
1656- SgObject ap ;
1657- int argc = ( int ) Sg_Length ( args ), i ;
1658- /* when argc == DEFAULT_VALUES_SIZE+1, it must be in pre-allocated
1659- buffer */
1660- if ( argc > DEFAULT_VALUES_SIZE + 1 ) {
1661- SG_ALLOC_VALUES_BUFFER ( vm , argc - DEFAULT_VALUES_SIZE - 1 );
1662- }
1663- vm -> ac = SG_CAR ( args );
1664- for ( i = 0 , ap = SG_CDR ( args ); SG_PAIRP ( ap ); i ++ , ap = SG_CDR ( ap )) {
1665- SG_VALUES_SET ( vm , i , SG_CAR ( ap ));
1666- }
1667- vm -> valuesCount = argc ;
1647+ return throw_continuation_end ( vm , args ) ;
1648+ }
1649+ }
1650+
1651+ static SgObject throw_continuation_end ( SgVM * vm , SgObject args )
1652+ {
1653+ vm -> pc = return_code ;
1654+ /* store arguments of the continuation to ac */
1655+ if ( SG_NULLP ( args )) { /* no value */
1656+ /* does this happen? */
1657+ vm -> ac = SG_UNDEF ;
1658+ vm -> valuesCount = 0 ;
1659+ } else if ( SG_NULLP ( SG_CDR ( args ))) { /* usual case */
1660+ vm -> ac = SG_CAR ( args );
1661+ vm -> valuesCount = 1 ;
1662+ } else { /* multi values */
1663+ SgObject ap ;
1664+ int argc = ( int ) Sg_Length ( args ), i ;
1665+ /* when argc == DEFAULT_VALUES_SIZE+1, it must be in pre-allocated
1666+ buffer */
1667+ if ( argc > DEFAULT_VALUES_SIZE + 1 ) {
1668+ SG_ALLOC_VALUES_BUFFER ( vm , argc - DEFAULT_VALUES_SIZE - 1 ) ;
16681669 }
1669- return vm -> ac ;
1670+ vm -> ac = SG_CAR (args );
1671+ for (i = 0 , ap = SG_CDR (args ); SG_PAIRP (ap ); i ++ , ap = SG_CDR (ap )) {
1672+ SG_VALUES_SET (vm , i , SG_CAR (ap ));
1673+ }
1674+ vm -> valuesCount = argc ;
16701675 }
1676+ return vm -> ac ;
16711677}
16721678
16731679static SgObject throw_continuation_cc (SgObject result , void * * data )
@@ -2002,17 +2008,22 @@ static SgObject throw_delimited_continuation_body(SgObject handlers,
20022008 PUSH_PROMPT_CONT (vm , new_prompt );
20032009 install_prompt (vm , new_prompt );
20042010
2005- /* Now compute and run wind-in handlers using the composable
2006- continuation path. We've already aborted to the prompt, so
2007- current vm->dynamicWinders is at the prompt's level. We need to
2008- wind into c's winders. */
2011+ /* If the prompt handler is not set, then don't execute winders
2012+ This behaviour is an emulation of the call/delimited-cc
2013+ implemented with abort/cc and call/comp.
2014+ I believe this is *not* a right solution, but it works...
2015+ */
2016+ if (!SG_FALSEP (node -> prompt -> handler )) {
2017+ /* If the prompts are not the same, then it's not an escape,
2018+ so reinstall the continuation by splicing*/
2019+ if (node -> prompt != prompt ) {
2020+ save_cont (vm );
2021+ vm -> cont = splice_cont (vm , c -> cont , prompt );
2022+ }
2023+ return throw_continuation_end (vm , args );
2024+ }
2025+ /* here we invoke the continuation like composable continuation */
20092026 SgObject wind_handlers = throw_cont_compute_handlers (c , prompt , vm );
2010-
2011- /* Sg_Printf(Sg_StandardErrorPort(), UC("delim: vm->dw: %A\n"), vm->dynamicWinders); */
2012- /* Sg_Printf(Sg_StandardErrorPort(), UC("delim: c->dw: %A\n"), c->winders); */
2013- /* Sg_Printf(Sg_StandardErrorPort(), UC("delim: hndlrs: %A\n"), wind_handlers); */
2014-
2015- /* Use the regular composable continuation body to process these handlers */
20162027 return throw_continuation_body (wind_handlers , c , args , prompt );
20172028 }
20182029}
0 commit comments