I don't know what Bonita is talking about (I rarely do), but stackless
co-routines can be much more efficient than co-routines with their own
stack, and simpler to implement. If each co-routine has its own stack
then you need some way to determine how big the stack should be, some
way to get that space (i.e., heap allocation), and switching between
stacks.
Stackless co-routines all run in the threads single stack. In effect,
the compiler will generate a dispatcher function which is a big switch
statement determining which co-routine to run at any given point, and
with each co-routine having a struct containing all its local state data
that needs to be preserved between calls - these state structs are then
local variables in the dispatcher function.
This gives you something with minimal overhead and complications, while
saving the programmer from writing this boilerplate state control manually.
However, it very clearly also reduces the flexibility and use-cases for
co-routines, compared to separate stacks. They are not a full
asynchronous cooperative multi-tasking solution.
Stackless co-routines have been used in C and C++ for decades, including
on tiny microcontrollers (see Adam Dunkels' "Protothreads"). Typically,
they are implemented using some hideous macros that hide switch
statements, and you need to make the state-preserving structs manually.
C++ language co-routines are, AFAICS, designed to give you the
benefits of such coding structures without the manual work.
I haven't tried them myself as yet, but I will do some day.