exec.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <bio.h>
  12. #include <ctype.h>
  13. #include <mach.h>
  14. #define Extern extern
  15. #include "acid.h"
  16. void
  17. error(char *fmt, ...)
  18. {
  19. int i;
  20. char buf[2048];
  21. va_list arg;
  22. /* Unstack io channels */
  23. if(iop != 0) {
  24. for(i = 1; i < iop; i++)
  25. Bterm(io[i]);
  26. bout = io[0];
  27. iop = 0;
  28. }
  29. ret = 0;
  30. gotint = 0;
  31. Bflush(bout);
  32. if(silent)
  33. silent = 0;
  34. else {
  35. va_start(arg, fmt);
  36. vseprint(buf, buf+sizeof(buf), fmt, arg);
  37. va_end(arg);
  38. fprint(2, "%L: (error) %s\n", buf);
  39. }
  40. while(popio())
  41. ;
  42. interactive = 1;
  43. longjmp(err, 1);
  44. }
  45. void
  46. unwind(void)
  47. {
  48. int i;
  49. Lsym *s;
  50. Value *v;
  51. for(i = 0; i < Hashsize; i++) {
  52. for(s = hash[i]; s; s = s->hash) {
  53. while(s->v->pop) {
  54. v = s->v->pop;
  55. free(s->v);
  56. s->v = v;
  57. }
  58. }
  59. }
  60. }
  61. void
  62. execute(Node *n)
  63. {
  64. Value *v;
  65. Lsym *sl;
  66. Node *l, *r;
  67. int64_t i, s, e;
  68. Node res, xx;
  69. static int stmnt;
  70. gc();
  71. if(gotint)
  72. error("interrupted");
  73. if(n == 0)
  74. return;
  75. if(stmnt++ > 5000) {
  76. Bflush(bout);
  77. stmnt = 0;
  78. }
  79. l = n->left;
  80. r = n->right;
  81. switch(n->op) {
  82. default:
  83. expr(n, &res);
  84. if(ret || (res.type == TLIST && res.store.l == 0 && n->op != OADD))
  85. break;
  86. prnt->right = &res;
  87. expr(prnt, &xx);
  88. break;
  89. case OASGN:
  90. case OCALL:
  91. expr(n, &res);
  92. break;
  93. case OCOMPLEX:
  94. decl(n);
  95. break;
  96. case OLOCAL:
  97. for(n = n->left; n; n = n->left) {
  98. if(ret == 0)
  99. error("local not in function");
  100. sl = n->sym;
  101. if(sl->v->ret == ret)
  102. error("%s declared twice", sl->name);
  103. v = gmalloc(sizeof(Value));
  104. v->ret = ret;
  105. v->pop = sl->v;
  106. sl->v = v;
  107. v->scope = 0;
  108. *(ret->tail) = sl;
  109. ret->tail = &v->scope;
  110. v->set = 0;
  111. }
  112. break;
  113. case ORET:
  114. if(ret == 0)
  115. error("return not in function");
  116. expr(n->left, ret->val);
  117. longjmp(ret->rlab, 1);
  118. case OLIST:
  119. execute(n->left);
  120. execute(n->right);
  121. break;
  122. case OIF:
  123. expr(l, &res);
  124. if(r && r->op == OELSE) {
  125. if(bool(&res))
  126. execute(r->left);
  127. else
  128. execute(r->right);
  129. }
  130. else if(bool(&res))
  131. execute(r);
  132. break;
  133. case OWHILE:
  134. for(;;) {
  135. expr(l, &res);
  136. if(!bool(&res))
  137. break;
  138. execute(r);
  139. }
  140. break;
  141. case ODO:
  142. expr(l->left, &res);
  143. if(res.type != TINT)
  144. error("loop must have integer start");
  145. s = res.store.ival;
  146. expr(l->right, &res);
  147. if(res.type != TINT)
  148. error("loop must have integer end");
  149. e = res.store.ival;
  150. for(i = s; i <= e; i++)
  151. execute(r);
  152. break;
  153. }
  154. }
  155. int
  156. bool(Node *n)
  157. {
  158. int true = 0;
  159. if(n->op != OCONST)
  160. fatal("bool: not const");
  161. switch(n->type) {
  162. case TINT:
  163. if(n->store.ival != 0)
  164. true = 1;
  165. break;
  166. case TFLOAT:
  167. if(n->store.fval != 0.0)
  168. true = 1;
  169. break;
  170. case TSTRING:
  171. if(n->store.string->len)
  172. true = 1;
  173. break;
  174. case TLIST:
  175. if(n->store.l)
  176. true = 1;
  177. break;
  178. }
  179. return true;
  180. }
  181. void
  182. convflt(Node *r, char *flt)
  183. {
  184. char c;
  185. c = flt[0];
  186. if(('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) {
  187. r->type = TSTRING;
  188. r->store.fmt = 's';
  189. r->store.string = strnode(flt);
  190. }
  191. else {
  192. r->type = TFLOAT;
  193. r->store.fval = atof(flt);
  194. }
  195. }
  196. void
  197. indir(Map *m, uint64_t addr, char fmt, Node *r)
  198. {
  199. int i;
  200. uint32_t lval;
  201. uint64_t uvval;
  202. int ret;
  203. uint8_t cval;
  204. uint16_t sval;
  205. char buf[512], reg[12];
  206. r->op = OCONST;
  207. r->store.fmt = fmt;
  208. switch(fmt) {
  209. default:
  210. error("bad pointer format '%c' for *", fmt);
  211. case 'c':
  212. case 'C':
  213. case 'b':
  214. r->type = TINT;
  215. ret = get1(m, addr, &cval, 1);
  216. if (ret < 0)
  217. error("indir: %r");
  218. r->store.ival = cval;
  219. break;
  220. case 'x':
  221. case 'd':
  222. case 'u':
  223. case 'o':
  224. case 'q':
  225. case 'r':
  226. r->type = TINT;
  227. ret = get2(m, addr, &sval);
  228. if (ret < 0)
  229. error("indir: %r");
  230. r->store.ival = sval;
  231. break;
  232. case 'a':
  233. case 'A':
  234. case 'W':
  235. r->type = TINT;
  236. ret = geta(m, addr, &uvval);
  237. if (ret < 0)
  238. error("indir: %r");
  239. r->store.ival = uvval;
  240. break;
  241. case 'B':
  242. case 'X':
  243. case 'D':
  244. case 'U':
  245. case 'O':
  246. case 'Q':
  247. r->type = TINT;
  248. ret = get4(m, addr, &lval);
  249. if (ret < 0)
  250. error("indir: %r");
  251. r->store.ival = lval;
  252. break;
  253. case 'V':
  254. case 'Y':
  255. case 'Z':
  256. r->type = TINT;
  257. ret = get8(m, addr, &uvval);
  258. if (ret < 0)
  259. error("indir: %r");
  260. r->store.ival = uvval;
  261. break;
  262. case 's':
  263. r->type = TSTRING;
  264. for(i = 0; i < sizeof(buf)-1; i++) {
  265. ret = get1(m, addr, (uint8_t*)&buf[i], 1);
  266. if (ret < 0)
  267. error("indir: %r");
  268. addr++;
  269. if(buf[i] == '\0')
  270. break;
  271. }
  272. buf[i] = 0;
  273. if(i == 0)
  274. strcpy(buf, "(null)");
  275. r->store.string = strnode(buf);
  276. break;
  277. case 'R':
  278. r->type = TSTRING;
  279. for(i = 0; i < sizeof(buf)-2; i += 2) {
  280. ret = get1(m, addr, (uint8_t*)&buf[i], 2);
  281. if (ret < 0)
  282. error("indir: %r");
  283. addr += 2;
  284. if(buf[i] == 0 && buf[i+1] == 0)
  285. break;
  286. }
  287. buf[i++] = 0;
  288. buf[i] = 0;
  289. r->store.string = runenode((Rune*)buf);
  290. break;
  291. case 'i':
  292. case 'I':
  293. if ((*machdata->das)(m, addr, fmt, buf, sizeof(buf)) < 0)
  294. error("indir: %r");
  295. r->type = TSTRING;
  296. r->store.fmt = 's';
  297. r->store.string = strnode(buf);
  298. break;
  299. case 'f':
  300. ret = get1(m, addr, (uint8_t*)buf, mach->szfloat);
  301. if (ret < 0)
  302. error("indir: %r");
  303. machdata->sftos(buf, sizeof(buf), (void*) buf);
  304. convflt(r, buf);
  305. break;
  306. case 'g':
  307. ret = get1(m, addr, (uint8_t*)buf, mach->szfloat);
  308. if (ret < 0)
  309. error("indir: %r");
  310. machdata->sftos(buf, sizeof(buf), (void*) buf);
  311. r->type = TSTRING;
  312. r->store.string = strnode(buf);
  313. break;
  314. case 'F':
  315. ret = get1(m, addr, (uint8_t*)buf, mach->szdouble);
  316. if (ret < 0)
  317. error("indir: %r");
  318. machdata->dftos(buf, sizeof(buf), (void*) buf);
  319. convflt(r, buf);
  320. break;
  321. case '3': /* little endian ieee 80 with hole in bytes 8&9 */
  322. ret = get1(m, addr, (uint8_t*)reg, 10);
  323. if (ret < 0)
  324. error("indir: %r");
  325. memmove(reg+10, reg+8, 2); /* open hole */
  326. memset(reg+8, 0, 2); /* fill it */
  327. leieee80ftos(buf, sizeof(buf), reg);
  328. convflt(r, buf);
  329. break;
  330. case '8': /* big-endian ieee 80 */
  331. ret = get1(m, addr, (uint8_t*)reg, 10);
  332. if (ret < 0)
  333. error("indir: %r");
  334. beieee80ftos(buf, sizeof(buf), reg);
  335. convflt(r, buf);
  336. break;
  337. case 'G':
  338. ret = get1(m, addr, (uint8_t*)buf, mach->szdouble);
  339. if (ret < 0)
  340. error("indir: %r");
  341. machdata->dftos(buf, sizeof(buf), (void*) buf);
  342. r->type = TSTRING;
  343. r->store.string = strnode(buf);
  344. break;
  345. }
  346. }
  347. void
  348. windir(Map *m, Node *addr, Node *rval, Node *r)
  349. {
  350. uint8_t cval;
  351. uint16_t sval;
  352. int32_t lval;
  353. Node res, aes;
  354. int ret;
  355. if(m == 0)
  356. error("no map for */@=");
  357. expr(rval, &res);
  358. expr(addr, &aes);
  359. if(aes.type != TINT)
  360. error("bad type lhs of @/*");
  361. if(m != cormap && wtflag == 0)
  362. error("not in write mode");
  363. r->type = res.type;
  364. r->store.fmt = res.store.fmt;
  365. r->store = res.store;
  366. switch(res.store.fmt) {
  367. default:
  368. error("bad pointer format '%c' for */@=", res.store.fmt);
  369. case 'c':
  370. case 'C':
  371. case 'b':
  372. cval = res.store.ival;
  373. ret = put1(m, aes.store.ival, &cval, 1);
  374. break;
  375. case 'r':
  376. case 'x':
  377. case 'd':
  378. case 'u':
  379. case 'o':
  380. sval = res.store.ival;
  381. ret = put2(m, aes.store.ival, sval);
  382. r->store.ival = sval;
  383. break;
  384. case 'a':
  385. case 'A':
  386. case 'W':
  387. ret = puta(m, aes.store.ival, res.store.ival);
  388. break;
  389. case 'B':
  390. case 'X':
  391. case 'D':
  392. case 'U':
  393. case 'O':
  394. lval = res.store.ival;
  395. ret = put4(m, aes.store.ival, lval);
  396. break;
  397. case 'V':
  398. case 'Y':
  399. case 'Z':
  400. ret = put8(m, aes.store.ival, res.store.ival);
  401. break;
  402. case 's':
  403. case 'R':
  404. ret = put1(m, aes.store.ival, (uint8_t*)res.store.string->string,
  405. res.store.string->len);
  406. break;
  407. }
  408. if (ret < 0)
  409. error("windir: %r");
  410. }
  411. void
  412. call(char *fn, Node *parameters, Node *local, Node *body, Node *retexp)
  413. {
  414. int np, i;
  415. Rplace rlab;
  416. Node *n, res;
  417. Value *v, *f;
  418. Lsym *s, *next;
  419. Node *avp[Maxarg], *ava[Maxarg];
  420. rlab.local = 0;
  421. na = 0;
  422. flatten(avp, parameters);
  423. np = na;
  424. na = 0;
  425. flatten(ava, local);
  426. if(np != na) {
  427. if(np < na)
  428. error("%s: too few arguments", fn);
  429. error("%s: too many arguments", fn);
  430. }
  431. rlab.tail = &rlab.local;
  432. ret = &rlab;
  433. for(i = 0; i < np; i++) {
  434. n = ava[i];
  435. switch(n->op) {
  436. default:
  437. error("%s: %d formal not a name", fn, i);
  438. case ONAME:
  439. expr(avp[i], &res);
  440. s = n->sym;
  441. break;
  442. case OINDM:
  443. res.store.cc = avp[i];
  444. res.type = TCODE;
  445. res.store.comt = 0;
  446. if(n->left->op != ONAME)
  447. error("%s: %d formal not a name", fn, i);
  448. s = n->left->sym;
  449. break;
  450. }
  451. if(s->v->ret == ret)
  452. error("%s already declared at this scope", s->name);
  453. v = gmalloc(sizeof(Value));
  454. v->ret = ret;
  455. v->pop = s->v;
  456. s->v = v;
  457. v->scope = 0;
  458. *(rlab.tail) = s;
  459. rlab.tail = &v->scope;
  460. v->store = res.store;
  461. v->type = res.type;
  462. v->set = 1;
  463. }
  464. ret->val = retexp;
  465. if(setjmp(rlab.rlab) == 0)
  466. execute(body);
  467. for(s = rlab.local; s; s = next) {
  468. f = s->v;
  469. next = f->scope;
  470. s->v = f->pop;
  471. free(f);
  472. }
  473. }