Mercurial > hg > CbC > old > device
changeset 16:ca0bce3b4810
struct copy
author | kono |
---|---|
date | Mon, 17 Jan 2000 16:08:16 +0900 |
parents | 6667dbd4f718 |
children | fdbf2fbc8140 |
files | Idea mc-parse.c test/tmp7.c |
diffstat | 3 files changed, 86 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/Idea Mon Jan 17 02:04:48 2000 +0900 +++ b/Idea Mon Jan 17 16:08:16 2000 +0900 @@ -1086,3 +1086,71 @@ join は? funcall を用意すると良いね。 + +Mon Jan 17 15:23:34 JST 2000 + + struct aa f1() { + return bb; + } + +みたいなのは? 関数の型か代入の型を見て、crn にpointerを渡して、 +あとでcopyしてから stack を畳む。 + + # bb=f1(aaa); + movl $bb,%eax + pushl %eax + movl $aaa,%eax + pushl %eax + call main2 + popl %edx + copy %eax,%edx,$400 + addl $400,%esp + # return a1; + +あ、でも、それだと、local変数を返したときに困るね。leave; ret; +してはいけなくて... + +あ、やっぱり、こういう場合はコピー先をmain2に引き渡しているみたいね。 + void f1(struct aa *ret) { + *ret = bb ; + return; + } +と同じか。これは簡単。 + f1().a[55] +みたいな場合は、局所変数に強制的に取ってしまうみたいね。それはそうだ... +が、うちの実装だとちょっと厳しいか。 + leal $-sizeof(struct),%esp + pushl %esp +なんだけど、関数呼び出しの途中ではできないから.... + + # main(ac,av) + # int ac; + .align 2 + .globl main + main: + .type main,@function + pushl %ebp + movl %esp,%ebp + pushl %ebx + pushl %ecx + pushl %edx + # char *av[]; + # { + # register int i; + # register char *p; + # int j = 3; + # struct { int b; void (*c)(struct aa); } q = {3,main1},r; + # + # j = 3; + subl $20,%esp + +このsublを後から指定してやればOk。 + +でも、それだと jump の時にずれない? ずれるか? ずれるね。うーん。 +実行時にチェックしてやるのも変だし。 + +まぁ、それほど必要な機能ではないんだけど。 + +これもcontinuationを渡してやると言う手法が使えないことはないんだが... + +関数呼び出しの最初にやってやればいいか。それでできるかな?
--- a/mc-parse.c Mon Jan 17 02:04:48 2000 +0900 +++ b/mc-parse.c Mon Jan 17 16:08:16 2000 +0900 @@ -506,7 +506,7 @@ { NMTBL *arg,*sfnptr; int sreg_var,t; - int stype; + int stype,smode; stype=type; sfnptr=fnptr; @@ -514,12 +514,14 @@ sreg_var=reg_var; reg_var=0; n->dsp=0; - if(mode!=GDECL && mode!=ADECL) error(DCERR); + smode = mode; + /* if(mode!=GDECL && mode!=ADECL) + error(DCERR); */ mode=ADECL; args= 0; for(;;) { if(sym==IDENT && nptr->sc!=TYPE) { - rplacad(n->ty,list2(INT,cadr(n->ty))); + rplacad(n->ty,glist2(INT,cadr(n->ty))); if (stmode==REGISTER && reg_var < MAX_REGISTER_VAR) { nptr->ty = INT; nptr->sc = REGISTER; @@ -553,14 +555,14 @@ def(arg); } } - rplacad(n->ty,glist2(INT,cadr(n->ty))); + rplacad(n->ty,glist2(t,cadr(n->ty))); if(sym==RPAR) break; } if (sym!=COMMA) error(DCERR); getsym(); } checksym(RPAR); - mode=GDECL; + mode=smode; reg_var=sreg_var; fnptr=sfnptr; type=stype;
--- a/test/tmp7.c Mon Jan 17 02:04:48 2000 +0900 +++ b/test/tmp7.c Mon Jan 17 16:08:16 2000 +0900 @@ -6,12 +6,15 @@ void tmp(void); -int -main0(int,char *[]); +struct aa +main0(); -main0(int ac,char *av[]) +struct aa +main0() { - return ac; + struct aa ccc; + ccc.a[55]=123; + return ccc; } void @@ -21,7 +24,7 @@ printf("main2 a1.a[55] %d\n",a1.a[55]); } -struct aa +void main1(struct aa a1) { printf("main1 a1.a[0] %d\n",a1.a[0]); @@ -30,7 +33,6 @@ main2(a1); else main2(aaa); - return a1; } @@ -41,10 +43,12 @@ register int i; register char *p; int j = 3; - struct { int b; void (*c)(/*struct aa*/); } q = {3,main1},r; + struct { int b; void (*c)(struct aa); } q = {3,main1},r; j = 3; + bbb = main0(); + j = main0().a[55]; printf("%d==3\n",q.b); r = q; printf("%d==3\n",r.b);