diff mc-inline.c @ 552:74bbea56b8e5

inline scope with gcc extension passed.
author kono
date Thu, 05 Jan 2006 13:16:26 +0900 (2006-01-05)
parents 73ebe9d82a9c
children 293f827ccfb2
line wrap: on
line diff
--- a/mc-inline.c	Wed Jan 04 14:55:46 2006 +0900
+++ b/mc-inline.c	Thu Jan 05 13:16:26 2006 +0900
@@ -306,10 +306,10 @@
     if (car(e1)==RINDIRECT) {
 	gen_indirect_goto(cadr(e1));
 	return ;
-    } else if (car(e1)==RLVAR||car(e1)==LVAR) {
+    } else if (car(e1)==RLVAR) {
 	gen_indirect_goto(e1);
 	return ;
-    } else if (car(e1)==FLABEL) {
+    } else if (car(e1)==LVAR||car(e1)==FLABEL) {
 	gen_jmp(cadr(e1));
         control=0;
         return ;
@@ -552,19 +552,27 @@
 static int
 p_decl(int e)
 {
-    // list4(ST_DECL,parse,(int)n,stmode);
-    int stmode=cadddr(e);
+    // list4(ST_DECL,parse,(int)n,list3(mode,stmode,ctmode));
+    int ctmode=cadddr(e);;
     NMTBL *n=(NMTBL*)caddr(e);
     int dsp = n->dsp;
     int v;
+    int sstmode = stmode;
+    int smode = mode;
     // in real partial evaluation, we have to check whether this variable
     // is used or not.
+    if (ctmode) {
+	mode = car(ctmode); stmode = cadr(ctmode); ctmode = caddr(ctmode);
+    }
     switch(stmode) {
     case EXTRN: case EXTRN1: case STATIC:
-	    // def(n,0); // ctmode?
-	    return pexpr(cadr(e));
-    case LLDECL:
-	v = list2(FLABEL,fwdlabel()); break;
+	// def(n,ctmode);      we don't need this. already done.
+	// stmode = sstmode;
+	stmode = sstmode;
+	mode = smode;
+	return pexpr(cadr(e));
+//    case LLDECL:          LLDECL is mode, not stmode (bad design)
+//	v = list2(FLABEL,fwdlabel()); break;
 #if 1
     case REGISTER:
 	switch(n->ty) {
@@ -583,11 +591,17 @@
 	break;
 #endif
     default:
-	v = list3(LVAR,new_lvar(size(n->ty)),(int)n);
+	if (n->sc==FLABEL)
+	    v = list3(LVAR,fwdlabel(),(int)n);
+	else
+	    v = list3(LVAR,new_lvar(size(n->ty)),(int)n);
     }
-    inline_lvars = glist2(v,inline_lvars);
+    if (n->sc!=FLABEL)
+	inline_lvars = glist2(v,inline_lvars);
     if (heap[pdisp+dsp]) error(-1);
     heap[pdisp+dsp]=v;
+    stmode = sstmode;
+    mode = smode;
     return pexpr(cadr(e));
 }
 
@@ -748,6 +762,7 @@
 	// should this done in p_decl? (in __label__?)
 	d = cadr(e);
 	if (!(e1=(heap[pdisp+d])))  {
+	    // error(-1);
 	    e1 = heap[pdisp+d]=list3(LVAR,fwdlabel(),caddr(e));
 	}
     }
@@ -1026,14 +1041,14 @@
     // these saved value should be some struct
     int sretlabel;
     NMTBL *sfnptr;
-    int svartable = pvartable;
-    int sretcont = retcont;
+    int svartable;
+    int sretcont;
     int scslabel = cslabel;
     int sdisp = pdisp;
-    int sret_register = ret_register;
-    int sret_reg_mode = ret_reg_mode;
-    int sinline_lvars = inline_lvars;
-    int slfree=lfree;
+    int sret_register;
+    int sret_reg_mode;
+    int sinline_lvars;
+    int slfree;
     // int slreg_count=lreg_count;
 
     int narg,arg;
@@ -1041,12 +1056,24 @@
     int e1 = attr_value(n,INLINE);
     int parse = car(e1);      // inline parse tree
     int arg_disp = cadr(e1);  // number of arguments
-    int e2,e3,t,e4,dots;
+    NMTBL *local_statics = (NMTBL*)cadddr(e1);  // local static list
+    int e2,e3,t,e4,e5,dots;
     int ret_type = function_type(cadddr(e),&dots);
     int fargtype;
     NMTBL *anptr;
 
-    // checkret();
+    checkret();
+    checkjmp(-1);
+
+    svartable = pvartable;
+    sretcont = retcont;
+    scslabel = cslabel;
+    sdisp = pdisp;
+    sret_register = ret_register;
+    sret_reg_mode = ret_reg_mode;
+    sinline_lvars = inline_lvars;
+    slfree=lfree;
+    // int slreg_count=lreg_count;
 
     sretlabel = retlabel;
     sfnptr = fnptr;
@@ -1068,8 +1095,12 @@
 
     /* inline function arguments */
     narg = 0;
-    for (e3 = e1 = reverse0(caddr(e)); e3; e3 = cadr(e3)) {
+    if (!fargtype) {
+	goto no_args;  // wrong number of arguments
+    }
+    for (e3 = e5 = reverse0(caddr(e)); e3; e3 = cadr(e3)) {
 	anptr = (NMTBL*)caddr(fargtype);
+	if (!anptr) break; // should not happen?
         t=caddr(e3);  // type
 	e4 = car(e3);
 	if (0 && is_const(e4) /* ||(is_memory(e3)&&is_readonly(e3)) */ ) {
@@ -1085,7 +1116,8 @@
 	narg ++;
 	fargtype = cadr(fargtype);
     }
-    caddr(e) = reverse0(e1);  // make it normal
+    caddr(e) = reverse0(e5);  // make it normal
+no_args:
     e2 = pexpr(parse);
     pdisp = sdisp;
     pvartable = svartable;
@@ -1101,6 +1133,13 @@
     if (retcont) error(STERR); // inline can't handle return/environment
 
     leave_scope();
+    if (local_statics && local_statics != &null_nptr) {
+	// append our local static variables to the parent list
+	n = local_statics;
+	while(n->next != &null_nptr) n=n->next;
+	n->next = local_static_list; local_static_list = local_statics;
+	cadddr(e1) = 0;  // prevent duplicate initialize
+    }
     while(inline_lvars) {
 	int e;
 	int l = car(inline_lvars);