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);