<?xml version="1.0" encoding="EUC-JP" ?>
<rss version="2.0">
<channel>
<title>めもがき:最新 5 日分</title>
<link>http://www.hi-matic.org/diary/</link>
<description>
the typical NetBSD style we did not document/advertise it.
</description>
<language>ja</language>
<item>
<title>[pcc] ほんやく！</title>
<link>http://www.hi-matic.org/diary/index.cgi?20100908#08-1</link>
<description>

&lt;h4&gt;&lt;a href=&quot;?20100908#08-1-1&quot; name=&quot;08-1-1&quot;&gt;@&lt;/a&gt; その2&lt;/h4&gt;
&lt;p &gt;
&lt;a href=&quot;http://www.hi-matic.org/diary/?20100824#24-1&quot;&gt;これ&lt;/a&gt;の続きですよ。
&lt;br &gt;前回に増していい加減な訳ですがクレームは/dev/nullへ。
&lt;/p&gt;

&lt;blockquote &gt;&lt;pre&gt;NODE構造体
  コンパイラの基本はツリー構造を使えちゅうことです、これはノード(NODE)という構造で表現されます。
  このノードは二項(binary)、単項(unary)あるいは末端(leaf)であって、それぞれ異なる型を表現します。
  全てのノードは操作(op)あるいは型(type)で構成されとります。

  ノードは一致するものがあれば命令(instruction)に変換されます、この処理は
  テーブルを検索することで行います。ノードからの出力は常にレジスタとみなされますが
  入力ノードは蟻ノード(?)とみなされるかもしれません。

  以下に一覧として中間ノードタイプをまとめました。フロントエンドはこれ以外のノードタイプをも
  追加する方法を選ぶかもしれません。表にしたのは(ツリー)構造の各ノード種別に使用される要素です。
　こいつらがフロントエンド(つまりpass1)かバックエンド(pass2)いずれかだけでしか有効でないなら
　名前の後ろに(1)か(2)と書き加えてあります。

注意事項:
	n_op(操作), n_type(型) そして n_qual(修飾子)はすべてのノードタイプに有効です。
	n_name(ノード名称)は決してぬるぽにはなりません、使用しない場合は "" になるとです。
	n_lval(左辺値)はその移植対象におけるもっとも大きな数値を保持できます。
	n_dcon(浮動小数点数定数)は最低でもその移植対象のlong double型を表現できます。
	全てのノードの変換結果は最後にはレジスタになると考えられます(?)。

末端ノード
        NAME
                メモリ上の位置の参照です、例えば変数にアクセスする場合など。
                NAMEから取得したアドレスはICONになります。
                n_lval - NAMEへのオフセットです、例えば a[3] とか
                n_sp (1) - NAMEのシンボルテーブル中のエントリになります
                n_name (2) - 名前の文字列を指すポインタです

        ICON
                数値型の定数値です、素の数値にもアドレス値にもなります。
                n_lval - 定数の値です
                n_sp (1) - アドレスの場合、シンボルテーブル中のエントリになります
                n_name (2) - シンボルの名前です

        FCON
                浮動少数点数の定数値です。
                n_dcon - 定数です

        REG
                レジスタのノードです、通常生成するのはレジスタアロケータの結果だけ
                ですが、しかしながらそのほかの場所でも生成されることがありえます。
		それは例をあげれば、ターゲットがレジスタ引数を持つ場合なんかです。
		n_rval - 数値でレジスタ変数になります

        OREG
                メモリ参照で、レジスタに対するオフセットになります。
                通常はpass2のoreg()内でUMUL-PLUS-REG-ICONのチェインにより作られます。
                ただし対象CPUがサポートしてる場合だけですが。
                n_lval - 定数でレジスタからのオフセットになります
                n_rval - 数値でレジスタのインデックス順になります

	TEMP
		一時ノードで、生成されるのはフロントエンドが値を
		レジスタでもメモリでもどっちにでも置けるようにするためです。
		レジスタアロケータは後でそれらを可能であればレジスタに置こうと試みます。
		n_rval - 数値で一時変数になります

&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
力尽きた。	
&lt;/p&gt;

&lt;h4&gt;&lt;a href=&quot;?20100908#08-1-2&quot; name=&quot;08-1-2&quot;&gt;@&lt;/a&gt;[pcc] ゆっくりによる pcc の内部解説&lt;/h4&gt;
&lt;p &gt;
つーことでコードリーディングのお時間、ゆっくりの声でよんでね！
&lt;/p&gt;

&lt;p &gt;
↑のドキュメントで触れられている
&lt;/p&gt;
&lt;ul &gt;&lt;li &gt;二項(binary)&lt;/li&gt;
&lt;li &gt;単項(unary)&lt;/li&gt;
&lt;li &gt;末端(leaf)&lt;/li&gt;
&lt;/ul&gt;
&lt;p &gt;
のノード分類ですが、実際にプログラム中では
&lt;br &gt;以下の定数として宣言されています。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;[ mip/manifest.h ]
46 /*
47  * Node types
48  */
49 #define LTYPE   02              /* leaf */
50 #define UTYPE   04              /* unary */
51 #define BITYPE  010             /* binary */
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p &gt;
そして{末端,単項,二項}ノード種別についても以下同文。
&lt;br &gt;ノード種類の説明は次回翻訳とあわせてです。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;[ mip/node.h ]
147 /*
148  * Value nodes.
149  */
150 #define NAME    2
151 #define ICON    4
152 #define FCON    5
...
234 #define MAXOP   58
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p &gt;
そして NODE は n_op フィールドにこのノード種別を保持します。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;[ mip/node.h ]
62 typedef struct node {
63         struct  node *next;
64         int     n_op;
65         union {
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p &gt;
ノード種別からノード分類へ変換するには、キバヤシよろしくノイズ除去に以下のマクロを使って
&lt;br &gt;「ガラッ話は聞いた世界は滅亡するAA略」してください。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;	optype(p-&gt;n_op) == BITYPE
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p &gt;
この optype はマクロで以下の場所で宣言されています。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;[ mip/pass2.h ]
400 #define optype(o)       (dope[o]&amp;TYFLG)
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p &gt;
このマクロ中で使われている dope は int 型の配列で以下のよに定義されとります。
&lt;br &gt;他にも opst ちうのもありますが、これについては後述。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;[ mip/pass2.h ]
360 extern  int dope[];     /* a vector containing operator information */
361 extern  char *opst[];   /* a vector containing names for ops */
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
配列の添字にはさっきのノード種別を使い、上限値は MAXOP となります。
&lt;/p&gt;

&lt;p &gt;
このdope及びopstはフロントエンドが mkdope() を呼んだタイミングで初期化されます。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;[ mip/common.c ]
319 int dope[DSIZE];
320 char *opst[DSIZE];
...
385 void
386 mkdope()
387 {
388         struct dopest *q;
389
390         for( q = indope; q-&gt;dopeop &gt;= 0; ++q ){
391                 dope[q-&gt;dopeop] = q-&gt;dopeval;
392                 opst[q-&gt;dopeop] = q-&gt;opst;
393         }
394 }
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p &gt;
初期化の為の元ソースは mip/common.c にテーブルが宣言されてる indope です。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;[ mip/common.c ]
322 struct dopest {
323         int dopeop;
324         char opst[8];
325         int dopeval;
326 } indope[] = {
327         { NAME, "NAME", LTYPE, },
328         { REG, "REG", LTYPE, },
...
382         { -1,   "",     0 },
383 };
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
ですので今回のINCR/DECRのpass2化のように種別を増やすなんてときに
&lt;br &gt;弄るのはここになります。
&lt;/p&gt;

&lt;p &gt;
opst は ccom -Xb などのデバックオプションでノードツリーをダンプする際に
&lt;br &gt;ノードタイプを画面表示可能な文字列に変換する用に以下同文、例えば mip/reader.c では
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;664         if (rv == FFAIL &amp;&amp; !q)
665                 comperr("Cannot generate code, node %p op %s", p,opst[p-&gt;n_op]);
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
のように使われています、まぁ今どきのプログラムならNODE構造体にtoString()とかto_strみたいな
&lt;br &gt;関数を用意するんでしょうが、なにせ30年前のコードですので以下略
&lt;/p&gt;

&lt;p &gt;
これらのノード種別は pass2 で有効なものであって、言語(=フロントエンド)非依存です。
&lt;br &gt;言語に依存するノード種別については C であれば cc/ccom/pass1.h に定義されています。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;539 /*
540  * C compiler first pass extra defines.
541  */
542 #define QUALIFIER       (MAXOP+1)
...
572 #define INCR            (MAXOP+26)
573 #define DECR            (MAXOP+27)
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
今回問題になっている INCR/DECR は今のところ言語依存の扱いですやね。
&lt;br &gt;なので pass1.h に定義され、pass2に渡される前に別の形に書き換えられてしまう運命なのです。
&lt;/p&gt;

&lt;p &gt;
話し戻してさっきの dope[] の添字にこの pass1 オンリーのノード種別を渡したりすると、たうぜん
&lt;br &gt;array index out of bounds の悲劇が発生しますので、cc/ccom/trees.c には cdope() という
&lt;br &gt;wrapper 関数が定義されていて、pass1ではこっちを使います。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;2647 int
2648 cdope(int op)
2649 {
2650         if (op &lt;= MAXOP)
2651                 return dope[op];
2652         switch (op) {
...
2696         case INCR:
2697         case DECR:
2698                 return BITYPE|ASGFLG;
2699         }
...
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p &gt;
同様に opst にも wrapper が用意されています。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;2601 char *
2602 copst(int op)
2603 {
2604         if (op &lt;= MAXOP)
2605                 return opst[op];
...
2632         SNAM(INCR,++)
2633         SNAM(DECR,--)
...
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p &gt;
今日はここまで。
&lt;/p&gt;
</description>
<pubDate>Wed, 08 Sep 2010 00:00:01 GMT</pubDate>
</item>
<item>
<title>[NetBSD] funopen(3) / open_wmemstream(3)</title>
<link>http://www.hi-matic.org/diary/index.cgi?20100907#07-1</link>
<description>
&lt;p &gt;
&lt;a href=&quot;http://www.hi-matic.org/diary/?20070629#29-1&quot;&gt;以前紹介した&lt;/a&gt; funopen(3) ですが seekfn って要するに fseek(3) の中の人なんだけども
&lt;br &gt;これ第2引数が fpos_t なのはちょっとイケてないよな。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;FILE *
funopen(void *cookie, int (*readfn)(void *, char *, int),
    int (*writefn)(void *, const char *, int),
    fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *));
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
fpos_t ってそもそも実装依存の opaque object なんだよね。
&lt;br &gt;NetBSD だと off_t と identical だけど、実装によっては構造体だったりする。
&lt;br &gt;例えば glibc2 なんかは
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;typedef struct
{
  __off_t __pos;
  __mbstate_t __state;
} _G_fpos_t;
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
となってますな。まぁ fpos_t が mbstate_t 持つ実装ってどうなんよとは思うけど、これは後述。
&lt;/p&gt;


&lt;p &gt;
よって funopen(3) を使う実装ってのは、seekfn 内で fpos_t を扱うところは
&lt;br &gt; OS dependendent(そもそも *BSD にしかないけど) かつ machine dependent になるのよね(fpos_t は MD)。
&lt;br &gt;一例をあげるに、
&lt;a href=&quot;http://www.hi-matic.org/diary/?20070629#29-1&quot;&gt; さっきのページのサンプルコード&lt;/a&gt;だと libz による gzip ファイル操作を
&lt;br &gt;通常の FILE 経由の read/write で隠ぺいしてるんだけど
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;fpos_t
seekfn(void *cookie, fpos_t offset, int whence)
{
	gzFile *p = (gzFile *)cookie;
	return (fpos_t)gzseek(p, (z_off_t)offset, whence);
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
本来 opaque であるべき fpos_t を無理矢理 z_off_t にキャストしてるけど
&lt;br &gt;厳密に言えばこれはアウト、でも他にやりようが無いので困っちゃうよなーと。
&lt;/p&gt;

&lt;p &gt;
一方同様に移植性はないけど、glibc2 の fopencookie(3) はその点マシで、
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;#define _G_off64_t        __off_t
...
#define _IO_off64_t _G_off64_t
...
typedef int __io_seek_fn (void *__cookie, _IO_off64_t *__pos, int __w);
...
typedef __io_seek_fn cookie_seek_function_t;
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
と off64_t という public type なので、fpos_t のように問題にはなりません。
&lt;/p&gt;

&lt;p &gt;
おまけ。
&lt;br &gt;さっき glibc2 は fpos_t の実装は off_t と mbstate_t なフィールドを持つ構造体だと書いたけど
&lt;br &gt;なぜそんな実装になっとるの？という話。
&lt;/p&gt;

&lt;p &gt;
これは glibc2 では open_wmemstream(3) なんかの実装用にワイド文字専用インタフェースを
&lt;br &gt;持ってるからなんですよな。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;/* Extra data for wide character streams.  */
struct _IO_wide_data
{
  wchar_t *_IO_read_ptr;        /* Current read pointer */
  wchar_t *_IO_read_end;        /* End of get area. */
...
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p &gt;
fwide(3) 的は stream すなわち FILE はバイト指向とワイド文字指向どちらかのモードを持つので
&lt;br &gt;そのへんパラノイアックに前者は open_memstream(3) 後者は open_wmemstream(3) として
&lt;br &gt;実装したよんということだと思うんだけど、これ N でもやろうとすると影響箇所が多杉で死ねる。
&lt;/p&gt;

&lt;p &gt;
そもそも通常のファイルってのはバイトなわけでして、ワイド文字なファイルというものは存在せんので
&lt;/p&gt;
&lt;ul &gt;&lt;li &gt;open_memstream(3) で FILE を開く、この時点では orientation(5) は未定&lt;/li&gt;
&lt;li &gt;バイト操作API(fputc/fwrite)で触ったらバイト指向、ワイド文字操作API(fputwc)で触ったらワイド文字指向&lt;/li&gt;
&lt;li &gt;fclose(3) して確定した(マルチ)バイト列をワイド文字に変換したけりゃ mbsrtowcs(3) 使え&lt;/li&gt;
&lt;/ul&gt;
&lt;p &gt;
が正しい実装だったと思うんだけどねぇ、まーでもすでに POSIX:2008 に open_wmemstream(3) も
&lt;br &gt;入ってしまってるので南無阿弥陀仏。
&lt;/p&gt;

&lt;p &gt;
まぁ open_wmemstream(3) の仕様では FILEにワイド文字用インタフェース設けずとも
&lt;br &gt;fflush(3) あるいは fclose(3) のタイミングでmbsrtowcs(3) で変換するでもいいのだけど
&lt;br &gt; N の場合 fflush(3) が呼ばれたことを知るためのフックが用意されていないので
&lt;br &gt;writefn が呼ばれる度に mbsnrtowcs(3) で変換せざるをえずとても効率が悪いのね。
&lt;br &gt;頭が痛いお。
&lt;/p&gt;

</description>
<pubDate>Tue, 07 Sep 2010 00:00:01 GMT</pubDate>
</item>
<item>
<title>[NetBSD] ATF(Automated Testing Framework) 義務化</title>
<link>http://www.hi-matic.org/diary/index.cgi?20100907#07-2</link>
<description>
&lt;p &gt;
&lt;a href=&quot;http://www.area51.gr.jp/~rin/diary/?date=20100907#p07&quot;&gt;だそうです&lt;/a&gt;。
&lt;/p&gt;
&lt;p &gt;
そもそも
&lt;a href=&quot;http://wiki.netbsd.org/tutorials/atf/&quot;&gt;チュートリアルが間違ってる&lt;/a&gt;という NetBSD クオリティ。
&lt;br &gt;テストケースのテンプレに以下の間違いがありまする、これ釣りなのかな。
&lt;/p&gt;
&lt;ul &gt;&lt;li &gt;ATF_TC()の引数の数がおかしい ×ATF_TC(tc, my_test_case) ○ATF_TC(my_test_case)&lt;/li&gt;
&lt;li &gt;ATF_TC_HEAD/ATF_TC_BODYの引数の順序が逆&lt;/li&gt;
&lt;/ul&gt;
&lt;p &gt;
とか。
&lt;/p&gt;

&lt;p &gt;
まぁATF独自のマクロだらけでテストの生産性が上がるどころか下がってるので
&lt;br &gt;htdocsのdocbook化のせいでドキュメント直す人が減ったのと同じ結末になる予感。
&lt;br &gt;正直早いとこYA(Yet Another)ATF作ろうぜという感じ。
&lt;br &gt;少なくとも libc のテストのような OS 非依存のテストケースは plain test の方が好ましい。
&lt;br &gt;とりあえず今回は以下のようなムリヤリな ifdef 書いて他のOSでも動くようにしたけど。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;#if defined(__NetBSD__)
#include &lt;atf-c.h&gt;
#else
#include &lt;assert.h&gt;
#include &lt;stdio.h&gt;
#define ATF_TC(arg0)            static void arg0##_head(void)
#define ATF_TC_HEAD(arg0, arg1) static void arg0##_head()
#define atf_tc_set_md_var(arg0, arg1, ...) do { \
        printf(__VA_ARGS__);                    \
        puts("");                               \
} while (/*CONSTCOND*/0)
#define ATF_TC_BODY(arg0, arg1) static void arg0##_body()
#define ATF_CHECK(arg0)         assert(arg0)
#define ATF_TP_ADD_TCS(arg0)    int main(void)
#define ATF_TP_ADD_TC(arg0, arg1) arg1##_head(); arg1##_body()
#define atf_no_error()          0
#endif
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p &gt;
YAATFを考えるならテストケースは JUnit みたいに
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;void
testFoo()
{
    ...
}
void
testBar()
{
    ...
}
int
main(void)
{
    testFoo();
    testBar();
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
と prefix 決めうちの plain testにして、runner は gcc -fPIE と dlopen(3)で
&lt;br &gt;みたいな感じじゃだめなのかなーと思ったり。
&lt;/p&gt;
</description>
<pubDate>Tue, 07 Sep 2010 00:00:02 GMT</pubDate>
</item>
<item>
<title>[C99] 小ネタ</title>
<link>http://www.hi-matic.org/diary/index.cgi?20100902#02-1</link>
<description>
&lt;p &gt;
唐突ですが、C99で導入された「構造体中の 0 長配列メンバ」ってーのは
&lt;br &gt;長さが不定の場合、配列ではなくポインタで宣言し動的に確保せなあかんので
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;struct foo {
	int x;
	char *y;
	^^^^^^^^
};
struct foo *
foo_new(size_t size)
{
	struct foo *f;
	f = malloc(sizeof(*f));
	^^^^^^^^^^^^^^^^^^^^^^^
	if (f == NULL)
		return NULL;
	f-&gt;y = malloc(size);
	^^^^^^^^^^^^^^^^^^^^
	if (f-&gt;y == NULL) {
		free(f);
		return NULL;
	}
	return f;
}
void
foo_delete(struct foo *f)
{
	free(f-&gt;y);
	free(f);
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
ちう具合に2回も malloc/free しなきゃならないのが面倒/高コストだからと
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;struct foo {
	int x;
	char y[1];
	^^^^^^^^^^
};
struct foo *
foo_new(size_t size)
{
	struct foo *f;
	f = malloc(sizeof(*f) + size - 1);
	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	if (f == NULL)
		return NULL;
}
void
foo_delete(struct foo *f)
{
	free(f);
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
ちゅーカリカリチューニングがナウなヤングにフィーバーしたのが由来なのですよな。
&lt;/p&gt;

&lt;p &gt;
しかしまぁ人間の欲望とは尽きないもので「size - 1 すら書きたくないでござる」という一派が
&lt;br &gt; C では元々 length zero の object は禁止という大原則をぐいっと曲げて
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;struct foo {
	int x;
	char y[];
	^^^^^^^^^
};
struct foo *
foo_new(size_t size)
{
	struct foo *f;
	f = malloc(sizeof(*f) + size);
	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	if (f == NULL)
		return NULL;
}
void
foo_delete(struct foo *f)
{
	free(f);
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
と、構造体の最後のメンバ変数だけはサイズを省略することで
&lt;br &gt;サイズを0として宣言できるちゅー文法を導入したのですよな。
&lt;/p&gt;

&lt;p &gt;
でもさーこれ、トラブル生むケースが無いわけではないのよね。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;struct foo {
	int x;
	char y[];
};
struct foo *
foo_new(size_t size)
{
	struct foo *f;
	f = malloc(sizeof(*f) + size);
	if (f == NULL)
		return NULL;
}
void
foo_delete(struct foo *f)
{
	free(f);
}

void
main(void)
{
	struct foo *f;
	f = foo_new(SIZE_MAX);
	assert(f == NULL);
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
このコードぱっと見だと、foo_new() の引数に SIZE_MAX
&lt;a href=&quot;#02-1-F1&quot; title=&quot;要は malloc_usable_size() 以上のサイズ、Nの場合この関数欲しいねーゆうとフルボッコ(ry &quot;&gt;&lt;small&gt;*1&lt;/small&gt;&lt;/a&gt;ちう
&lt;br &gt;確実に malloc(3) が失敗するであろうサイズを指定してるので、foo_new()の戻りは
&lt;br &gt; NULL だと想定していますが、それは甘いスイーツ(笑)
&lt;/p&gt;

&lt;p &gt;
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;malloc(sizeof(*f) + SIZE_MAX);
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
どう見ても integer overflow です、本当にありが(ry
&lt;br &gt;つまり malloc(sizeof(*f)-1) になりますので foo_new() は予想に反して成功してしまいま。
&lt;br &gt;おおこわいこわい。
&lt;/p&gt;

&lt;p &gt;
ちうことで
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;struct foo *
foo_new(size_t size)
{
	struct foo *f;
	size_t alloc;

	if (SIZE_MAX - size &lt; sizeof(*f)) {
		errno = ENOMEM;
		return NULL;
	}
	f = malloc(sizeof(*f) + size);
	if (f == NULL)
		return NULL;
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
という integer overflow 対策じうやうです。
&lt;br &gt;ぱっとパラノイア〜ぱっとパラノイア〜
&lt;/p&gt;

&lt;p &gt;
まぁそもそも今時のマシンでこんなチューニングすんなって話だよなーと。
&lt;/p&gt;
&lt;hr style=&quot;width: 40%; text-align: left;&quot;&gt;&lt;div&gt;
&lt;small&gt;&lt;a name=&quot;02-1-F1&quot; href=&quot;?20100902#02-1-F1&quot; title=&quot;02-1-F1&quot;&gt;*1&lt;/a&gt;:要は malloc_usable_size() 以上のサイズ、Nの場合この関数欲しいねーゆうとフルボッコ(ry
&lt;/small&gt;&lt;br&gt;&lt;br&gt;&lt;/div&gt;
</description>
<pubDate>Thu, 02 Sep 2010 00:00:01 GMT</pubDate>
</item>
<item>
<title>[pcc] _Bool + INCR/DECR(後置インクリメント/デクリメント命令) 問題</title>
<link>http://www.hi-matic.org/diary/index.cgi?20100826#26-1</link>
<description>
&lt;h4&gt;&lt;a href=&quot;?20100826#26-1-1&quot; name=&quot;26-1-1&quot;&gt;@&lt;/a&gt; そもそも&lt;/h4&gt;
&lt;p &gt;
なぜ pcc は INCR/DECR を pass1 で扱っているのかよーわかりませ。
&lt;br &gt;これはUNIX V7のソースに含まれる pcc の過去の歴史がすっぽすっぽ抜け落ちてるので
&lt;br &gt;もうコード読んで恐山気分でイマジンノーヘブンするしかないのですよね…
&lt;/p&gt;

&lt;p &gt;
ありそうな理由としては、pass2 は言語非依存なんで、インクリメント演算のない言語(f77とか)を考慮して
&lt;br &gt;pass1 に移しから(なんというパラノイア)とか、そもそも pass2 で扱うのがめんどくさいので pass1 で消しこんでるとか。
&lt;br &gt;＃ なんとなく後者の気がするなぁ…
&lt;/p&gt;

&lt;p &gt;
そもそも最適化を考えた場合、x += 1 なんかは i386 なら addl $1,x を incl x にした方が効率いいのですよな。
&lt;br &gt;なんで
&lt;/p&gt;
&lt;ul &gt;&lt;li &gt;INCR/DECR は pass2 で処理する為、pass1で何もしない&lt;/li&gt;
&lt;li &gt;pass2ではインクリメント/デクリメント命令のない cpu は INCR/DECR を PLUSEQ/MINUSEQ に書換する&lt;/li&gt;
&lt;li &gt;〃 ある cpu は pass2 の最適化で PLUSEQ/MINUSEQ が 1 の場合、INCR/DECR に書換する&lt;/li&gt;
&lt;/ul&gt;
&lt;p &gt;
というのがいいような気がする。
&lt;/p&gt;

&lt;p &gt;
ところが現状だと
&lt;/p&gt;
&lt;ul &gt;&lt;li &gt;pass1 は INCR/DECR は PLUSEQ/MINUSEQ に書換する&lt;/li&gt;
&lt;li &gt;更に PLUSEQ/MINUSEQ は PLUS/MINUS つまり x = x + 1 / x = x - 1 に書換する&lt;/li&gt;
&lt;li &gt;pass2 での最適化のため PLUS/MINUS が1の場合、SONE ちう bit を立てておく&lt;/li&gt;
&lt;li &gt;pass2 ではインクリメント/デクリメント命令のない cpu は SONE を無視する&lt;/li&gt;
&lt;li &gt;〃 ある cpu は SONE が立ってたらインクリメント/デクリメント命令で最適化を行う&lt;/li&gt;
&lt;/ul&gt;
&lt;p &gt;
という感じ、関連するtable.cのエントリは↓とか。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;[ arch/i386/table.c ]
647 { PLUS,         INAREG|FOREFF,
648         SAREG|SNAME|SOREG,      TWORD|TPOINT,
649         SONE,   TANY,
650                 0,      RLEFT,
651                 "       incl AL\n", },
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
まぁpass1でやるかpass2でやるかの問題ですが。
&lt;br &gt;これはソース相当読み込まないと答えだせなさそうだなー。
&lt;/p&gt;

&lt;p &gt;
明日くらいに和訳続きと、別途に俺オリジナルでソース解説やりますね。
&lt;/p&gt;
</description>
<pubDate>Thu, 26 Aug 2010 00:00:01 GMT</pubDate>
</item>
<item>
<title>[pcc] ほんやく</title>
<link>http://www.hi-matic.org/diary/index.cgi?20100824#24-1</link>
<description>
&lt;p &gt;
ヒマみてボチボチ訳していこうかと、原文は
&lt;a href=&quot;http://pcc.ludd.ltu.se/ftp/pub/pcc-docs/targdocs.txt&quot;&gt;こちら&lt;/a&gt;。
&lt;br &gt;意味が通じればいいやレベルなので苦情とか撲滅運動な人は/dev/nullへどうぞ。
&lt;/p&gt;
&lt;blockquote &gt;&lt;pre&gt;移植者のためのPCCガイド

アブストラクト
  この書は新たな対象にPCCを移植しようと考えている人向けです。
  移植作業に足る内部構造と、対象依存のサブルーチンについての解説を扱います。
  関連して読んで置いたほうがいいのは、オリジナルのPCCのドキュメントでしょう。

イントロダクション
  PCCは元はSteven C. Johnsonによって、今から30年以上も昔に書かれました。
  内部は多くの変更が加えられましたが、それでもなお基本構造はまだ変わらず元のままです。
  このコンパイラは概念的に2つのパートに分割することができます; 言語に特定する処理を
  扱うフロントエンド部分と、最適化とアセンブリコードの生成を行うバックエンド部です。

  この分割構造によって、他のフロントエンドを追加し易くなっています。
  その実例としてこのパッケージにはf77のフロントエンドも含めてあります。

パス
  コンパイラは先ほど述べた通り、異なる2つのパスから成り立ちますので
  この2つをそれぞれ別のプログラムとその中間ストアとして作り上げることは可能でしょう。
  まー普通はそこまでやりません、必要になった人がやればいいんじゃないでしょうか。
  でもこの2つを分割することを念頭におけば、よりクリーンな内部構造になりますし
  後から異なる言語フロントエンドをぶちこむのもより簡単になります。

  この全てのシンボルテーブル情報の(パース)結果と、(中間ストア)データ生成は全て
  pass1で終了し、pass2では最適化とアセンブリコードの生成のみを行います。
  pass2は関数の式木全体を保存します、式木はpass1から渡され最適化とレジスタの割り当てを
  して関数を完成させます。

  関数のコードはinterpass構造体のリンクリストで表現されます。
  このリンクリストは必ずプロローグ(interpass_prolog構造体)で始まり、同様に
  エピローグで終わりますが、これはフロントエンドによって詰め込まれます。
  この構造体の中身の詳細については、mip/manifest.h を参照してください。

型情報
  PCCで型情報はTWORD(ふつーはint)に変換されます、これにはビットシフトが使われます。
  最下位5bitは基本型を表現します、いわゆるintとかfloatとかなんかです。
  まぁそれだけじゃなしにFTN、PTRそしてARYと論理和されもします、必要に応じてですが。
  例えば、(PTR|LONG) はlong型へのポインタです。いくつかのマクロがこの型情報を操作するため
  用意されています; INCREF(LONG) これは前の(PTR|LONG)と同じです。他のマクロについては
  詳細は mip/manifest.h を参照してください。


シンボルテーブル
  そうのうち書く
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p &gt;
続きはまた後日。
&lt;/p&gt;

&lt;p &gt;
というかllvmでいいんじ(ry
&lt;/p&gt;

&lt;p &gt;
んで
&lt;a href=&quot;http://www.hi-matic.org/diary/?20070926#26-1&quot;&gt;例の問題&lt;/a&gt;も
&lt;a href=&quot;http://www.hi-matic.org/distfiles/pcc/&quot;&gt;patch&lt;/a&gt;更新、
&lt;a href=&quot;http://www.hi-matic.org/diary/?20071130#30-1&quot;&gt;こっちの作業&lt;/a&gt;を進めるためにまずはドキュメントちゃんと読みましょう週間開始。
&lt;/p&gt;

</description>
<pubDate>Tue, 24 Aug 2010 00:00:01 GMT</pubDate>
</item>

</channel>
</rss>
