1 #include "cc.h" 2 3 static char *kwd[] = 4 { 5 "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn", 6 "$delete", "$do", "$else", "$eval", "$head", "$if", 7 "$local", "$loop", "$return", "$tail", "$then", 8 "$union", "$whatis", "$while", 9 }; 10 static char picklestr[] = "\tbp = pickle(bp, ep, un, "; 11 12 static char* 13 pmap(char *s) 14 { 15 int i, bot, top, new; 16 17 bot = 0; 18 top = bot + nelem(kwd) - 1; 19 while(bot <= top){ 20 new = bot + (top - bot)/2; 21 i = strcmp(kwd[new]+1, s); 22 if(i == 0) 23 return kwd[new]; 24 25 if(i < 0) 26 bot = new + 1; 27 else 28 top = new - 1; 29 } 30 return s; 31 } 32 33 Sym* 34 picklesue(Type *t) 35 { 36 int h; 37 Sym *s; 38 39 if(t != T) 40 for(h=0; h<nelem(hash); h++) 41 for(s = hash[h]; s != S; s = s->link) 42 if(s->suetag && s->suetag->link == t) 43 return s; 44 return 0; 45 } 46 47 Sym* 48 picklefun(Type *t) 49 { 50 int h; 51 Sym *s; 52 53 for(h=0; h<nelem(hash); h++) 54 for(s = hash[h]; s != S; s = s->link) 55 if(s->type == t) 56 return s; 57 return 0; 58 } 59 60 char picklechar[NTYPE]; 61 Init picklecinit[] = 62 { 63 TCHAR, 'C', 0, 64 TUCHAR, 'b', 0, 65 TSHORT, 'd', 0, 66 TUSHORT, 'u', 0, 67 TLONG, 'D', 0, 68 TULONG, 'U', 0, 69 TVLONG, 'V', 0, 70 TUVLONG, 'W', 0, 71 TFLOAT, 'f', 0, 72 TDOUBLE, 'F', 0, 73 TARRAY, 'a', 0, 74 TIND, 'X', 0, 75 -1, 0, 0, 76 }; 77 78 static void 79 pickleinit(void) 80 { 81 Init *p; 82 83 for(p=picklecinit; p->code >= 0; p++) 84 picklechar[p->code] = p->value; 85 86 picklechar[TINT] = picklechar[TLONG]; 87 picklechar[TUINT] = picklechar[TULONG]; 88 if(types[TINT]->width != types[TLONG]->width) { 89 picklechar[TINT] = picklechar[TSHORT]; 90 picklechar[TUINT] = picklechar[TUSHORT]; 91 if(types[TINT]->width != types[TSHORT]->width) 92 warn(Z, "picklemember int not long or short"); 93 } 94 95 } 96 97 void 98 picklemember(Type *t, long off) 99 { 100 Sym *s, *s1; 101 static int picklecharinit = 0; 102 103 if(picklecharinit == 0) { 104 pickleinit(); 105 picklecharinit = 1; 106 } 107 s = t->sym; 108 switch(t->etype) { 109 default: 110 Bprint(&outbuf, " T%d\n", t->etype); 111 break; 112 113 case TIND: 114 if(s == S) 115 Bprint(&outbuf, 116 "%s\"p\", (char*)addr+%ld+_i*%ld);\n", 117 picklestr, t->offset+off, t->width); 118 else 119 Bprint(&outbuf, 120 "%s\"p\", &addr->%s);\n", 121 picklestr, pmap(s->name)); 122 break; 123 124 case TINT: 125 case TUINT: 126 case TCHAR: 127 case TUCHAR: 128 case TSHORT: 129 case TUSHORT: 130 case TLONG: 131 case TULONG: 132 case TVLONG: 133 case TUVLONG: 134 case TFLOAT: 135 case TDOUBLE: 136 if(s == S) 137 Bprint(&outbuf, "%s\"%c\", (char*)addr+%ld+_i*%ld);\n", 138 picklestr, picklechar[t->etype], t->offset+off, t->width); 139 else 140 Bprint(&outbuf, "%s\"%c\", &addr->%s);\n", 141 picklestr, picklechar[t->etype], pmap(s->name)); 142 break; 143 case TARRAY: 144 Bprint(&outbuf, "\tfor(_i = 0; _i < %ld; _i++) {\n\t", 145 t->width/t->link->width); 146 picklemember(t->link, t->offset+off); 147 Bprint(&outbuf, "\t}\n\t_i = 0;\n\tUSED(_i);\n"); 148 break; 149 150 case TSTRUCT: 151 case TUNION: 152 s1 = picklesue(t->link); 153 if(s1 == S) 154 break; 155 if(s == S) { 156 Bprint(&outbuf, "\tbp = pickle_%s(bp, ep, un, (%s*)((char*)addr+%ld+_i*%ld));\n", 157 pmap(s1->name), pmap(s1->name), t->offset+off, t->width); 158 } else { 159 Bprint(&outbuf, "\tbp = pickle_%s(bp, ep, un, &addr->%s);\n", 160 pmap(s1->name), pmap(s->name)); 161 } 162 break; 163 } 164 } 165 166 void 167 pickletype(Type *t) 168 { 169 Sym *s; 170 Type *l; 171 Io *i; 172 int n; 173 char *an; 174 175 if(!debug['P']) 176 return; 177 if(debug['P'] > 1) { 178 n = 0; 179 for(i=iostack; i; i=i->link) 180 n++; 181 if(n > 1) 182 return; 183 } 184 s = picklesue(t->link); 185 if(s == S) 186 return; 187 switch(t->etype) { 188 default: 189 Bprint(&outbuf, "T%d\n", t->etype); 190 return; 191 192 case TUNION: 193 case TSTRUCT: 194 if(debug['s']) 195 goto asmstr; 196 an = pmap(s->name); 197 198 Bprint(&outbuf, "uchar*\npickle_%s(uchar *bp, uchar *ep, int un, %s *addr)\n{\n\tint _i = 0;\n\n\tUSED(_i);\n", an, an); 199 for(l = t->link; l != T; l = l->down) 200 picklemember(l, 0); 201 Bprint(&outbuf, "\treturn bp;\n}\n\n"); 202 break; 203 asmstr: 204 if(s == S) 205 break; 206 for(l = t->link; l != T; l = l->down) 207 if(l->sym != S) 208 Bprint(&outbuf, "#define\t%s.%s\t%ld\n", 209 s->name, 210 l->sym->name, 211 l->offset); 212 break; 213 } 214 } 215 216 void 217 picklevar(Sym *s) 218 { 219 int n; 220 Io *i; 221 Type *t; 222 Sym *s1, *s2; 223 224 if(!debug['P'] || debug['s']) 225 return; 226 if(debug['P'] > 1) { 227 n = 0; 228 for(i=iostack; i; i=i->link) 229 n++; 230 if(n > 1) 231 return; 232 } 233 t = s->type; 234 while(t && t->etype == TIND) 235 t = t->link; 236 if(t == T) 237 return; 238 if(t->etype == TENUM) { 239 Bprint(&outbuf, "%s = ", pmap(s->name)); 240 if(!typefd[t->etype]) 241 Bprint(&outbuf, "%lld;\n", s->vconst); 242 else 243 Bprint(&outbuf, "%f\n;", s->fconst); 244 return; 245 } 246 if(!typesu[t->etype]) 247 return; 248 s1 = picklesue(t->link); 249 if(s1 == S) 250 return; 251 switch(s->class) { 252 case CAUTO: 253 case CPARAM: 254 s2 = picklefun(thisfn); 255 if(s2) 256 Bprint(&outbuf, "complex %s %s:%s;\n", 257 pmap(s1->name), pmap(s2->name), pmap(s->name)); 258 break; 259 260 case CSTATIC: 261 case CEXTERN: 262 case CGLOBL: 263 case CLOCAL: 264 Bprint(&outbuf, "complex %s %s;\n", 265 pmap(s1->name), pmap(s->name)); 266 break; 267 } 268 } 269