pickle.c 4.6 KB

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