#リリースノートを書いてたら char-ci=? 等をちゃんとしたcase mappingに対応させるのを忘れてたのに気づいた (upcaseして比べてるけど、foldcaseで比べないと)。が、差が出る場合ってあるかな。σとςはupcaseすれば同じになっちゃうしな。
#İ (大文字のiの上に点) と i の比較がまずいか。後者はupcaseすると I だからな。
#むー、r6rsコンパチにするにはchar-ci=?とかを不定長引数にする必要があるか… 押し込んじゃおうかな。
#あ、違う違う。UnicodeDataのSpecialCasings.txtによれば言語独立の時 İ (U+0130) のfoldcaseはそれ自身だ。r6rsのcase mappingは言語独立のマッピングしか扱わないから、(char-ci=? İ i) => #f は正しい。
#ではupcaseとfoldcaseでの比較で差が出る場合はあるのか、目視でざっと探すくらいだとわからんな。ふたつの大文字が同じ小文字にマップされて、別の小文字がその大文字のどちらかにマップされるような場合、なんだろうけど。
#む。RT: @_enami: gauche, NetBSD i386 だとエラーになるな
#test sockaddr equal? (equal? un1 un3): expects #t => got #f になりました
#diff --git a/ext/net/addr.c b/ext/net/addr.c
index 9d2dd89..0b2371f 100644
--- a/ext/net/addr.c
+++ b/ext/net/addr.c
@@ -167,5 +167,6 @@ static int sockaddr_un_compare(ScmObj x, ScmObj y, int equal
if (xx->addrlen == yy->addrlen
- && memcmp(xx->addr.sun_path, yy->addr.sun_path, xx->addrlen) == 0) {
+ && memcmp(xx->addr.sun_path, yy->addr.sun_path,
+ xx->addrlen - offsetof(struct sockaddr_un, sun_path)) == 0) {
return 0; /* (equal? x y) => #t */
} else {
#で通りました。
#ああそうか。addrlenは構造体全体のサイズか。さて、そうするとoffsetofのそれも構造体のレイアウトに依存しちゃうな (sun_pathの後ろに余分なフィールドがあった場合)。
#じゃあ、 sizeof(xx->addr.sun_path) ですかね
#ですね。初期化時にそれでチェックしてるし。
#後もう一つ、
#Testing utility scripts ... failed.
discrepancies found. Errors are:
test gauche-package compile: expects #t => got "gosh: \"error\": Compile Error: Compile Error: Compile Error: Compile Error: Compile Error: Compile Error: cannot find file \"gauche/collection\" in *load-path* (\"../../../lib\" \"../../../src\" \"/usr/local/share/gauche-0.9/site/lib\" \"/usr/local/share/gauche-0.9/0.9.2_pre1/lib\" \"/usr/local/share/gauche/site/lib\" \"/usr/local/share/gauche/0.9/lib\")\n\"../../../lib/gauche/sequence.sci\":3:(define-module gauche.sequence (use ...\n\n\"../../../lib/gauche/record.scm\":34:(define-module gauche.record (use ga ...\n\n\"../../../lib/gauche/threads.sci\":3:(define-module gauche.threads (use g ...\n\n\"../../../lib/gauche/process.scm\":285:(define (%setup-iomap proc redirs) ( ...\n\n\"../../../lib/gauche/config.scm\":2:(define-module gauche.config (use ga ...\n\n\"./../run\":1:(use gauche.config)\n\n"
#というエラーがでました。
#プリコンパイルされたファイルがどっかに残ってるってことはありませんか? それでそんなエラーを見たことがあるような気が。
#amd64 で build した tree をそのままコピーしたのでそういうことかもしれません。きれいな tree でやりなおしてみます。
#ほんとは対応しないとならないんだろうけど、いつもあれっと思って綺麗にしてやりなおすと出てこないのでなんとなくそのままになっちゃってる。
#あと、amd64 の clang で compile したら、
#load.c:1255:70: warning: control reaches end of non-void function [-Wreturn-type
]
ScmObj Scm_CurrentLoadHistory() { PARAM_REF(Scm_VM(), load_history); }
^
load.c:1256:67: warning: control reaches end of non-void function [-Wreturn-type
]
ScmObj Scm_CurrentLoadNext() { PARAM_REF(Scm_VM(), load_next); }
^
load.c:1257:67: warning: control reaches end of non-void function [-Wreturn-type
]
ScmObj Scm_CurrentLoadPort() { PARAM_REF(Scm_VM(), load_port); }
^
load.c:1258:74: warning: control reaches end of non-void function [-Wreturn-type
]
ScmObj Scm_LoadMainScript() { PARAM_REF(Scm_VM(), load_main_script); }
^
4 warnings generated.
#と警告されました。return 要りますよね。
#うわ。Linuxで通ってたのはたまたまか。
#Linux/gccね。
#git pushした。
#ちなみに amd64 で clang で build したものは、 srfi-19 のテストで algorithmR から返ってこないようです。
#algorithmRは機種依存ありそうだけどsrfi-19でっていうのは不思議だなあ。具体的にどのテストかわかりますか?
#すみません、テストじゃなかった。precomp でした。
#../../src/gosh -ftest ../../src/precomp -e ./srfi-19.scm
#で、gdb で attach すると algolitymR のところでずっとループしているみたいです。
#もしよければ、src/number.cの3537行目のScm_Printfをuncommentして実行してみていただけますか
#z=1.570796326794896558,
x=70742377520284401891557702107136,
y=2288627485048242176
f=15707963267948966
m=7074237752028479
e=-16, k=-52
z=1.570796326794896558,
x=70742377520284401891557702107136,
y=2298627485048242176
f=15707963267948966
m=7074237752028480
e=-16, k=-52
z=1.570796326794896558,
x=70742377520284401891557702107136,
y=70742377520284810000000000000000
f=15707963267948966
m=7074237752028481
e=-16, k=-52
z=1.570796326794896558,
x=70742377520284401891557702107136,
y=2298627485048242176
f=15707963267948966
m=7074237752028480
e=-16, k=-52
z=1.570796326794896558,
x=70742377520284401891557702107136,
y=70742377520284810000000000000000
f=15707963267948966
m=7074237752028481
e=-16, k=-52
#この m=...80 と m=...81 を繰り返しているようです。
#src/ の下で ./gosh -ftest して、REPLに 1.570796326794896558 をタイプするとどうなりますか。
#あと 1.5707963267948966 と。
#gosh> 1.570796326794896558
z=1.570796326794896558,
x=7074237752028440000004585861152768,
y=7074237752028440000000000000000000
f=1570796326794896558
m=7074237752028440
e=-18, k=-52
1.5707963267948966
gosh>
#後者はとまらないですね。
#z=1.570796326794896558,
x=70742377520284401891557702107136,
y=2298627485048242176
f=15707963267948966
m=7074237752028480
e=-16, k=-52
z=1.570796326794896558,
x=70742377520284401891557702107136,
y=70742377520284810000000000000000
f=15707963267948966
m=7074237752028481
e=-16, k=-52
#それだな。pi/2を読もうとして引っかかってる。けれど特に境界値みたいなものでもないし、そこらへんは整数演算ばっかりなんで機種依存も考えにくいんだが、なんだろう。
#最初のほうは、
#gosh> 1.5707963267948966
z=1.570796326794896558,
x=70742377520284401891557702107136,
y=1898627485048242176
f=15707963267948966
m=7074237752028440
e=-16, k=-52
z=1.570796326794896558,
x=70742377520284401891557702107136,
y=1908627485048242176
f=15707963267948966
m=7074237752028441
e=-16, k=-52
#この先はアセンブラ読まないとだめですかね。
#そんなに微妙な計算はしてないと思うんだけどなあ。演算は基本的に全部API呼び出しになってるはずだし。
#念のため、L3542でScm_NumCmp()の戻り値でswitchかけてるけどもし戻り値が-1,0,1以外だとはまるかも。L3565のdefault:をcase 1:にして、switchの最後にdefault: Scm_Panic("boo");とかやってみるとどうなります?
#動作は変わらないですね。とまらないです。
#gcc 版とくらべるとそもそも最初の y の値が違いますね。
#循環になるぶぶんを手計算してみると、m=7074237752028481 になった次の y が70742377520284800000000000000000 にならないとおかしいのに 2298627485048242176 で循環してる。bignum演算のバグかな?
#L3604の直後に、y,m,eの値を表示させるとどうなりますか?
#y = Scm_Mul(m, iexpt10(-e)) これの後。
#m=7074237752028481 になった後でそこを通る時は m=7074237752028480, e=-16, y=70742377520284800000000000000000 が期待されるけど…
#z=1.570796326794896558,
x=70742377520284401891557702107136,
y=70742377520284810000000000000000
f=15707963267948966
m=7074237752028481
e=-16, k=-52
*y=70742377520284401891557702107136
m=2298627485048242176
e=-16
#desita
#でした。
#mもyも壊れとる… あれ、でもその後でfor(;;)の頭に戻ってmとyがまたprintされてますよね、そこでは値が戻ってる?
#戻ってるとしたらclangの最適化が何か悪さしてるかも。
#for loop 直後の printf では y, m とも二つの値を繰り返していますね。
#つまりScm_Mulの直後のy,mの値と、for(;;)の直後のy,mの値が一致してないってことですね?
#あ、ちょっとまって。まちがえてる
#y,mじゃなくて x,y print してた。
#z=1.570796326794896558,
x=70742377520284401891557702107136,
y=70742377520284810000000000000000
f=15707963267948966
m=7074237752028481
e=-16, k=-52
*y=2298627485048242176
m=7074237752028480
e=-16
#です。
#おっけー。Scm_Mulがおかしいですねえ。ちなみにその直前のループでは m=7074237752028481, y=70742377520284810000000000000000, e=-16ですよね?
#*y=70742377520284810000000000000000
m=7074237752028481
e=-16
#ですね。
#それはちゃんと計算してるんだなあ。Scm_Mulをテストするには… REPLで (* 7074237752028480 (expt 10 16)) を評価すると?
#またとまらないですね
#なんと。それが止まらなくなるとな。まあこれで怪しいのはbignum_mul_siかな。
#z=1.570796326794896558,
x=70742377520284401891557702107136,
y=1898627485048242176
f=15707963267948966
m=7074237752028440
e=-16, k=-52
*y=1908627485048242176
m=7074237752028441
e=-16
z=1.570796326794896558,
x=70742377520284401891557702107136,
y=1908627485048242176
f=15707963267948966
m=7074237752028441
e=-16, k=-52
*y=1918627485048242176
m=7074237752028442
e=-16
#またこれがでてくるんですけど
#え、あそうか。exptがlib/gauche/numerical.scmをautoloadして、その中にpi/2のリテラルが書いてあるからそこでつっかえちゃうんだ。
#(* 7074237752028480 (%expt 10 16)) ではどうですか。
#定数にすればいいのかな
#gosh> (* 7074237752028480 (%expt 10 16))
2298627485048242176
#どわー。それですね。しかし中途半端な数でバグが出るもんだな。前の数を+1や-1してみたらちゃんとした答えになります? +1の方は少なくともなるはずだな。
#gosh> (* 7074237752028481 (%expt 10 16))
70742377520284810000000000000000
gosh> (* 7074237752028479 (%expt 10 16))
2288627485048242176
gosh>
#です。
#小さい方はやっぱりおかしいですね。念のため、gauche/config.hのSCM_TARGET_I386は#undefになってますよね?
#% grep SCM_TARG gauche/config.h
/* #undef SCM_TARGET_I386 */
#ですね。
#あれ、待てよ、そのこの計算は64bitならfixnum * fixnum -> bignumか。
#なんか見えてきたぞ。gosh> (logand (* 7074237752028480 (expt 10 16)) (- (expt 2 64) 1))
2298627485048242176
#(gdb) p (7074237752028479 * 10000000000000000)
$1 = 2288627485048242176
#scm_mulでオーバーフローチェックがちゃんと動いてないか (number.c, L1815)
#そんな感じですね
#br Scm_BignumMulSI して (* 7074237752028479 10000000000000000)
を計算してもとまらない
#k/v1 != v0 は成立してると思うんだけどな。
#fprintf(stderr, "%d, %d, %d\n",
v1 != 0, k/v1 != v0, !SCM_SMALL_INT_FITS(k));
ha
#は 1, 0, 0 でした。
#7074237752028481からは正常に動くってのは、オーバーフロー後の乗算結果2308627485048242176がfixnumの最大値2305843009213693951を越えるんで、SMALL_INT_FITSの条件を外れるからか
#ええー、じゃあk/v1 == v0ってこと? amd64って128bitの整数演算レジスタなんてあったっけ? kがそいつに載っかっちゃってるとか。
#SSEか何かでそういう乗算があるんかな。
#そんな器用なことはしてないような。やっぱりバグってる?
#00000000000049d0 <scm_mul>:
/*
* Multiplication
*/
/*static*/ ScmObj scm_mul(ScmObj arg0, ScmObj arg1, int vmp)
{
49d0: 55 push %rbp
49d1: 48 89 e5 mov %rsp,%rbp
if (SCM_INTP(arg0)) {
49d4: 41 57 push %r15
49d6: 41 56 push %r14
49d8: 41 54 push %r12
49da: 53 push %rbx
49db: 48 83 ec 20 sub $0x20,%rsp
49df: 48 89 f8 mov %rdi,%rax
49e2: 48 83 e0 03 and $0x3,%rax
49e6: 48 83 f8 01 cmp $0x1,%rax
49ea: 89 d3 mov %edx,%ebx
49ec: 49 89 f6 mov %rsi,%r14
49ef: 49 89 ff mov %rdi,%r15
49f2: 0f 85 77 02 00 00 jne 4c6f <scm_mul+0x29f>
if (SCM_INTP(arg1)) {
49f8: 4c 89 f1 mov %r14,%rcx
49fb: 48 83 e1 03 and $0x3,%rcx
49ff: 0f 84 8c 00 00 00 je 4a91 <scm_mul+0xc1>
4a05: 48 83 f9 02 cmp $0x2,%rcx
4a09: 0f 84 0d 01 00 00 je 4b1c <scm_mul+0x14c>
4a0f: 48 83 f9 01 cmp $0x1,%rcx
4a13: 0f 85 4f 09 00 00 jne 5368 <scm_mul+0x998>
long v0 = SCM_INT_VALUE(arg0);
4a19: 49 c1 ff 02 sar $0x2,%r15
long v1 = SCM_INT_VALUE(arg1);
4a1d: 49 c1 fe 02 sar $0x2,%r14
long k = v0 * v1;
4a21: 4c 89 f3 mov %r14,%rbx
4a24: 49 0f af df imul %r15,%rbx
4a28: 49 bc 00 00 00 00 00 mov $0x2000000000000000,%r12
4a2f: 00 00 20
4a32: 49 01 dc add %rbx,%r12
4a35: 48 b8 ff ff ff ff ff mov $0x3fffffffffffffff,%rax
4a3c: ff ff 3f
4a3f: 49 39 c4 cmp %rax,%r12
4
#途中で切れた。
#4a3f: 49 39 c4 cmp %rax,%r12
4a42: 0f 97 c0 seta %al
fprintf(stderr, "%d, %d, %d\n",
4a45: 44 0f b6 c0 movzbl %al,%r8d
4a49: bf 30 01 00 00 mov $0x130,%edi
4a4e: 48 03 3d 00 00 00 00 add 0x0(%rip),%rdi # 4a55 <scm
_mul+0x85>
/*static*/ ScmObj scm_mul(ScmObj arg0, ScmObj arg1, int vmp)
{
if (SCM_INTP(arg0)) {
if (SCM_INTP(arg1)) {
long v0 = SCM_INT_VALUE(arg0);
long v1 = SCM_INT_VALUE(arg1);
4a55: 4d 85 f6 test %r14,%r14
long k = v0 * v1;
fprintf(stderr, "%d, %d, %d\n",
4a58: 0f 95 c0 setne %al
4a5b: 0f b6 d0 movzbl %al,%edx
4a5e: 48 8d 35 00 00 00 00 lea 0x0(%rip),%rsi # 4a65 <scm
_mul+0x95>
4a65: 31 c9 xor %ecx,%ecx
4a67: 30 c0 xor %al,%al
4a69: e8 00 00 00 00 callq 4a6e <scm_mul+0x9e>
4a6e: 48 b8 00 00 00 00 00 mov $0x4000000000000000,%rax
4a75: 00 00 40
4a78: 49 39 c4 cmp %rax,%r12
v1 != 0, k/v1 != v0, !SCM_SMALL_INT_FITS(k));
/* TODO: need a better way to check overflow */
if ((v1 != 0 && k/v1 != v0) || !SCM_SMALL_INT_FITS(k)) {
4a7b: 0f 82 94 09 00 00 jb 5415 <scm_mul+0xa45>
ScmObj big = Scm_MakeBignumFromSI(v0);
4a81: 4c 89 ff mov %r15,%rdi
4a84: e8 00 00 00 00 callq 4a89 <scm_mul+0xb9>
return Scm_BignumMulSI(SCM_BIGNUM(big), v1);
4a89: 48 89 c7 mov %rax,%rdi
4a8c: 4c 89 f6 mov %r14,%rsi
4a8f: eb 35 jmp 4ac6 <scm_mul+0xf6>
} else {
return Scm_MakeInteger(k);
}
}
#そんな中、時間切れ。帰宅します。
#どもありがとうございました。
#ざっと見たところk/v1を計算してる様子がない? k = v0*v1だからk/v1 == v0に決まってるだろ、と考えちゃってるのかなあ。
#あ、そうそう。ext/net/addr.cとsrc/load.cのfixまで入れたバージョンが http://practical-scheme.net/vault/Gauche-0.9.2_pre2.tgz に置いてあります。これからテストしたい方はそちらを使って下さい。 #doc の typo です。
diff --git a/doc/modutil.texi b/doc/modutil.texi
index 72f9497..aa36dea 100644
--- a/doc/modutil.texi
+++ b/doc/modutil.texi
@@ -14284,7 +14284,7 @@ You can alo pass multiple domains to @var{domain-name}.
@file{.po} ファイル名)を C の gettext と同じように指定します。
@code{#f} を @var{domain-name} として渡すと、デフォルトのドメインアクセサ
手続きが得られます。また、複数のドメインを @var{domain-name}にあたえる
-ことができあす。
+ことができます。
@c COMMON
@example
(textdomain '("myapp" "gimp")) ; search 1st myapp, then gimp
#Mahalo-
#% cat x.c
int f(long x, long y) { long k = x * y; return (k/y != x); }
% cat x.s
.file "x.c"
.text
.globl f
.align 16, 0x90
.type f,@function
f: # @f
.Leh_func_begin0:
# BB#0:
xorl %eax, %eax
ret
.Ltmp0:
.size f, .Ltmp0-f
.Leh_func_end0:
#これ、だめですよねえ?
#http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf をみたら An example of undefined behavior is the behavior on integer overflow. って書いてありました。 #ふーむ、オーバフローした場合に結果がどうなってるかは一切保証されないということか。
#とするとCでportableにオーバフローを検出するのは不可能ってことかな。
#128bit integerが使えればそれで検出、そうでなければ32bit digitで多倍長乗算みたいなことをやって検出するしかないか。
#アセンブラならフラグ見るだけなのになあ。C言語は低レベルだから効率よくてシステム記述に向いてるとか嘘っぱちだあaaaa。
#高級アセンブラの名が廃りますね。
#ffs っぽいことするのとどっちが速いでしょうね。
#long longでも64bitか (gcc)。むー、世の中大抵x86_64だからここだけインラインアセンブリって誘惑にもかられるけど、gccのインライン
#asmがclangでも使えるなんて都合の良いことは…無いよねえ…
#clang は一応 gcc compati も目指しているはずなので、ある程度は使えるんじゃないですかね?
#ふむ。http://clang.llvm.org/compatibility.html#inline-asm "In general, Clang is highly compatible with the GCC inline assembly extensions" #__GNUC__ とかも predefine しちゃってるくらいだし
#完全にportableなfallbackはいずれ考えるとして、x86_64向けの最適化を兼ねてやっちゃおうかな。
#gccだったら-fwrapv、他のコンパイラは諦めるとかで。。
#(インラインasmはWin64 + VisualC++で使えないのが地味に困る。。)
#ポータブルなfallbackは既にgauche/arith.hにあった。half wordを使って計算してるので安全なはず。
##なるほど > -fwrapv。でもgcc限定になるならインラインasmでも似たようなものかも (i386, x86_64以外のcpuごめん)。
#gosh> (* 7074237752028480 (%expt 10 16))
70742377520284800000000000000000
#になりました。
#やた。そしたらoverflow関係の未定義動作っぽい箇所はarith.hのマクロを使うようにして、別途x86_64用に (今のi386用と同様に) インラインアセンブラを用意するかなあ。ポータブルなSMULOVはコード量がかなり増えるんだが仕方ない。