pickle.c 4.7 KB

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