Shiro Kawai
shiro****@lava*****
2008年 6月 25日 (水) 17:22:33 JST
記憶の糸を辿ってみたんですが、vals[]の最後の要素にあふれた値を リストで格納しておくことで多値の値の個数の制限を無くそうとか 思ってた気がします。そのせいで最後の要素の扱いに混乱があるのかも しれません。 とりあえずもう一回見直して判断しようと思います。 --shiro From: "MIURA Yasuyuki" <kokos****@gmail*****> Subject: [Gauche-devel-jp] 多値の個数について Date: Sat, 21 Jun 2008 01:55:31 +0900 > こんにちは。Gaucheを読んで学習している三浦です。 > > 多値の個数の限界はコメントを見る限りでは 20 (SCM_VM_MAX_VALUES) となっていますが、 > 実際に values に与えることができる値の限界は19個になっています。 > 他にもそのようになっているところがありました。 > > そこで多値の個数の限界が SCM_VM_MAX_VALUES になるようにしてみました。 > 変数と何番目の要素扱いであるかは以下のイメージで行いましたがあっていたでしょうか。 > 変数 : val0, vals[0], vals[1], ... vals[18] > 順番 : 0, 1, 2, 19 > > Subversion の trunk に変更を加え、テストをしたところ全て通ってはいます。 > パッチは SVN の trunk のところで svn diff したものです。 > よろしくお願いします。 > > Index: src/vm.c > =================================================================== > --- src/vm.c (revision 6265) > +++ src/vm.c (working copy) > @@ -189,7 +189,7 @@ > v->pc = PC_TO_RETURN; > v->base = NULL; > v->val0 = SCM_UNDEFINED; > - for (i=0; i<SCM_VM_MAX_VALUES; i++) v->vals[i] = SCM_UNDEFINED; > + for (i=0; i<SCM_VM_MAX_VALUES-1; i++) v->vals[i] = SCM_UNDEFINED; > v->numVals = 1; > > v->handlers = SCM_NIL; > @@ -1705,8 +1705,8 @@ > INCR_PC; > > for (i=0; i<nargs; i++) { > - if (i >= SCM_VM_MAX_VALUES-1) { > - PUSH_ARG(vm->vals[SCM_VM_MAX_VALUES-1]); > + if (i >= SCM_VM_MAX_VALUES-2) { > + PUSH_ARG(vm->vals[SCM_VM_MAX_VALUES-2]); > break; > } > PUSH_ARG(vm->vals[i]); > @@ -1723,10 +1723,10 @@ > } > CASE(SCM_VM_VALUES) { > int nargs = SCM_VM_INSN_ARG(code), i; > - if (nargs >= SCM_VM_MAX_VALUES) > + if (nargs > SCM_VM_MAX_VALUES) > VM_ERR(("values got too many args")); > VM_ASSERT(nargs -1 <= SP - vm->stackBase); > - if (nargs > 0) { > + if (nargs > 1) { > for (i = nargs-1; i>0; i--) { > vm->vals[i-1] = VAL0; > POP_ARG(VAL0); > @@ -1740,10 +1740,10 @@ > int nvals; > VM_ASSERT(ENV); > nvals = (int)ENV->size; > - SCM_ASSERT(nvals < SCM_VM_MAX_VALUES); > + SCM_ASSERT(nvals <= SCM_VM_MAX_VALUES); > vm->numVals = nvals; > for (; nvals > 1; nvals--) { > - POP_ARG(vm->vals[nvals-1]); > + POP_ARG(vm->vals[nvals-2]); > } > POP_ARG(VAL0); > NEXT; > @@ -2791,8 +2791,9 @@ > > vm->val0 = proc; > for (i=0; i<nargs; i++) { > - if (i == SCM_VM_MAX_VALUES-1) { > + if (i == SCM_VM_MAX_VALUES-2) { > vm->vals[i] = args; > + break; > } > vm->vals[i] = SCM_CAR(args); > args = SCM_CDR(args); > @@ -3106,7 +3107,7 @@ > if (ep) { > /* There's an escape point defined by with-error-handler. */ > ScmObj target, current; > - ScmObj result = SCM_FALSE, rvals[SCM_VM_MAX_VALUES]; > + ScmObj result = SCM_FALSE, rvals[SCM_VM_MAX_VALUES-1]; > int numVals = 0, i; > > /* To conform SRFI-34, the error handler (clauses in 'guard' form) > @@ -3161,7 +3162,7 @@ > SCM_END_PROTECT; > > /* Install the continuation */ > - for (i=0; i<numVals; i++) vm->vals[i] = rvals[i]; > + for (i=0; i<numVals-1; i++) vm->vals[i] = rvals[i]; > vm->numVals = numVals; > vm->val0 = result; > vm->cont = ep->cont; > @@ -3410,7 +3411,7 @@ > return SCM_CAR(args); > } else if (nargs < 1) { > return SCM_UNDEFINED; > - } else if (nargs >= SCM_VM_MAX_VALUES) { > + } else if (nargs > SCM_VM_MAX_VALUES) { > Scm_Error("too many values passed to the continuation"); > } > > @@ -3521,7 +3522,7 @@ > nvals = 1; > SCM_FOR_EACH(cp, SCM_CDR(args)) { > vm->vals[nvals-1] = SCM_CAR(cp); > - if (nvals++ >= SCM_VM_MAX_VALUES) { > + if (nvals++ >= SCM_VM_MAX_VALUES-1) { > Scm_Error("too many values: %S", args); > } > } > Index: src/gauche/vm.h > =================================================================== > --- src/gauche/vm.h (revision 6265) > +++ src/gauche/vm.h (working copy) > @@ -386,7 +386,7 @@ > being accumulated. This is a part of > continuation. */ > ScmObj val0; /* Value register. */ > - ScmObj vals[SCM_VM_MAX_VALUES]; /* Value register for multiple values */ > + ScmObj vals[SCM_VM_MAX_VALUES-1]; /* Value register for multiple values */ > int numVals; /* # of values */ > > ScmObj handlers; /* chain of active dynamic handlers */ > > ---- > 三浦 康幸 > ココサブ @ http://wiki.monaos.org/pukiwiki.php?Reading%20Gauche