ざっと調べた。言語を実装する時に疑問に思う細かい部分はまだ拾いきれていない(探せばありそう)。
コルーチン内で別の関数を呼び出す場合、その関数の呼び出し中に現在のコルーチンをsuspend不可とする制限をもたせる(call stackが深い部分でsuspendを許可しない)。 その制限によって、コルーチンのsuspend時に関数のcall stackを全て保存する必要がなくなる。
stackが必要なのはコルーチン実行時のみ(実行時は通常の関数と同等のため、これは必要)で、suspend時はローカル変数と次回の実行ポイント程度をコンテキストに保持しておけばよい。
そういう意味でstackless?
軽量にみえる(保持する情報が少ない)
coroutine内で無名関数を作るようなユースケースで、その無名関数の中ではcoroutineのsuspendは出来ない。 例えば、map関数の途中でsuspend(yield)するようなコード。
coroutine内のコード生成が複雑になりそうだが…(yieldする部分でbasicblockを切ってswitchに変換するような機構で作れる。状態機械への変換) デストラクタの機構がある言語だとどうするんだろうか…
コア言語のサポートが必要にみえる。yield部分のコード生成が必要なため。
stacklessと対象に、いかなるタイミングでcorontineをsuspendすることができる。 こちらはcall stackと実行レジスタを全てコンテキストで保持するため。
ライブラリ実装でなんとかできる。
メモリ使用量やコンテキストスイッチが重そう(call stack保持であったりstackを切り替えるのでキャッシュとかなんかありそう)
伸長するスタックをヒープか現在のスタックに作ってそれをコンテキストとしてコルーチンを呼び出す方法が一般的?