データ構造について自分メモ
ScmVM、ScmEscapePoint、ScmContFrame、ScmCompiledCode とか。
- ScmVM 型は ScmEscapePoint 型の属性を持っている
- ScmVM 型は ScmCompiledCode 型の属性を持っている
- よく見たら ScmVM 型は ScmContFrame 型の属性も持っている
というコトは ScmVMRec 構造体を少なくともざっくり理解するのは必要不可欠。
by sixth sense
構造体定義を見てて cstack というメンバの記述が微妙に気になる
ScmCStack *cstack; /* current escape point. see the comment of "C stack rewinding" below. */
ScmCStack 型ってどっかで見たな、と思いつつ下にある、というコメントを発見。もしかするとこれも Reading Gauche 方面では記述がありそげ。
このあたりはなんとなくイメージできるんですが、Scm_VMDefaultExceptionHandler() では vm->escapePoint を元に巻き戻しをしてるんだよなぁ。これも Reading Gauche にあるか
escapePoint と cstack の違いって何だろ。
ScmEscapePoint *escapePoint;/* chain of escape points (a kind of one-shot continuation). used by system's default exception handler to escape from the error handlers. */
よく見てみると SCM_UNWIND_PROTECT 関連のマクロ定義の中身で使われてるのが cstack でマクロの中の sigsetjmp() の戻りが 0 の処理 (longjmp() の飛び先) は escapePoint が使われているのは分かるんですがそっから先がまだ暗い。
とは言え、Scm_VMDefaultExceptionHandler() はちょっとだけイメージできたカンジかも。ここを手がかりにもう少し掘る事ができるかどうか。
Scm_Error() を見てみる
引用しつつ微妙な点を挙げつらう
void Scm_Error(const char *msg, ...) { ScmObj e; ScmVM *vm = Scm_VM(); va_list args; if (SCM_VM_RUNTIME_FLAG_IS_SET(vm, SCM_ERROR_BEING_HANDLED)) { e = Scm_MakeError(SCM_MAKE_STR("Error occurred in error handler")); Scm_VMThrowException(vm, e); }
最初のこれは ScmVM の Runtime flags を見てスデに HANDLED な状態であればエラーハンドラの中でエラーが発生したと見て、な処理に見える。
で、そうでなければ HANDLED な状態にして
SCM_VM_RUNTIME_FLAG_SET(vm, SCM_ERROR_BEING_HANDLED); SCM_UNWIND_PROTECT { va_start(args, msg); e = Scm_MakeError(Scm_Vsprintf(msg, args, TRUE)); va_end(args); } SCM_WHEN_ERROR { /* TODO: should check continuation? */ e = Scm_MakeError(SCM_MAKE_STR("Error occurred in error handler")); } SCM_END_PROTECT;
ここで SCM_UNWIND_PROTECT マクロが出てくる。ちょっと誤解してたんですが
#define SCM_UNWIND_PROTECT \ do { \ ScmCStack cstack; \ cstack.prev = Scm_VM()->cstack; \ cstack.cont = NULL; \ Scm_VM()->cstack = &cstack; \ if (sigsetjmp(cstack.jbuf, FALSE) == 0) {
の最後の条件式によれば longjmp() からの戻り先は SCM_WHEN_ERROR 以降になるはずなんですが、ちょっとワケワカらんくなってるな。何かカンチガいしてますかねぇ。
あと ScmVM の cstack にローカル変数なアドレスぶち込んじゃってますが大丈夫なんだろうか。このあたりの語彙があまり無いから弱いんですが、こうしたヤリ方がデフォルトだったりするんだろうな。まだまだイメージするソレからは遠い。
とりあえず setjmp されて cstack な chain には追加されるのは間違いない、んだろうか。