exec.c (9985B)
1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <ctype.h> 5 #include <mach.h> 6 #define Extern extern 7 #include "acid.h" 8 9 void 10 error(char *fmt, ...) 11 { 12 int i; 13 char buf[2048]; 14 va_list arg; 15 16 /* Unstack io channels */ 17 if(iop != 0) { 18 for(i = 1; i < iop; i++) 19 Bterm(io[i]); 20 bout = io[0]; 21 iop = 0; 22 } 23 24 ret = 0; 25 gotint = 0; 26 Bflush(bout); 27 if(silent) 28 silent = 0; 29 else { 30 va_start(arg, fmt); 31 vseprint(buf, buf+sizeof(buf), fmt, arg); 32 va_end(arg); 33 fprint(2, "%Z: (error) %s\n", buf); 34 } 35 while(popio()) 36 ; 37 interactive = 1; 38 longjmp(err, 1); 39 } 40 41 void 42 unwind(void) 43 { 44 int i; 45 Lsym *s; 46 Value *v; 47 48 for(i = 0; i < Hashsize; i++) { 49 for(s = hash[i]; s; s = s->hash) { 50 while(s->v->pop) { 51 v = s->v->pop; 52 free(s->v); 53 s->v = v; 54 } 55 } 56 } 57 } 58 59 void 60 execute(Node *n) 61 { 62 Value *v; 63 Lsym *sl; 64 Node *l, *r; 65 int i, s, e; 66 Node res, xx; 67 static int stmnt; 68 69 gc(); 70 if(gotint) 71 error("interrupted"); 72 73 if(n == 0) 74 return; 75 76 if(stmnt++ > 5000) { 77 Bflush(bout); 78 stmnt = 0; 79 } 80 81 l = n->left; 82 r = n->right; 83 84 switch(n->op) { 85 default: 86 expr(n, &res); 87 if(ret || (res.type == TLIST && res.store.u.l == 0)) 88 break; 89 prnt->right = &res; 90 expr(prnt, &xx); 91 break; 92 case OASGN: 93 case OCALL: 94 expr(n, &res); 95 break; 96 case OCOMPLEX: 97 decl(n); 98 break; 99 case OLOCAL: 100 for(n = n->left; n; n = n->left) { 101 if(ret == 0) 102 error("local not in function"); 103 sl = n->sym; 104 if(sl->v->ret == ret) 105 error("%s declared twice", sl->name); 106 v = gmalloc(sizeof(Value)); 107 v->ret = ret; 108 v->pop = sl->v; 109 sl->v = v; 110 v->scope = 0; 111 *(ret->tail) = sl; 112 ret->tail = &v->scope; 113 v->set = 0; 114 } 115 break; 116 case ORET: 117 if(ret == 0) 118 error("return not in function"); 119 expr(n->left, ret->val); 120 longjmp(ret->rlab, 1); 121 case OLIST: 122 execute(n->left); 123 execute(n->right); 124 break; 125 case OIF: 126 expr(l, &res); 127 if(r && r->op == OELSE) { 128 if(bool(&res)) 129 execute(r->left); 130 else 131 execute(r->right); 132 } 133 else if(bool(&res)) 134 execute(r); 135 break; 136 case OWHILE: 137 for(;;) { 138 expr(l, &res); 139 if(!bool(&res)) 140 break; 141 execute(r); 142 } 143 break; 144 case ODO: 145 expr(l->left, &res); 146 if(res.type != TINT) 147 error("loop must have integer start"); 148 s = res.store.u.ival; 149 expr(l->right, &res); 150 if(res.type != TINT) 151 error("loop must have integer end"); 152 e = res.store.u.ival; 153 for(i = s; i <= e; i++) 154 execute(r); 155 break; 156 } 157 } 158 159 int 160 bool(Node *n) 161 { 162 int true = 0; 163 164 if(n->op != OCONST) 165 fatal("bool: not const"); 166 167 switch(n->type) { 168 case TINT: 169 if(n->store.u.ival != 0) 170 true = 1; 171 break; 172 case TFLOAT: 173 if(n->store.u.fval != 0.0) 174 true = 1; 175 break; 176 case TSTRING: 177 if(n->store.u.string->len) 178 true = 1; 179 break; 180 case TLIST: 181 if(n->store.u.l) 182 true = 1; 183 break; 184 } 185 return true; 186 } 187 188 void 189 convflt(Node *r, char *flt) 190 { 191 char c; 192 193 c = flt[0]; 194 if(('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { 195 r->type = TSTRING; 196 r->store.fmt = 's'; 197 r->store.u.string = strnode(flt); 198 } 199 else { 200 r->type = TFLOAT; 201 r->store.u.fval = atof(flt); 202 } 203 } 204 205 void 206 indir(Map *m, u64int addr, char fmt, Node *r) 207 { 208 int i; 209 u32int ival; 210 u64int vval; 211 int ret; 212 u8int cval; 213 u16int sval; 214 char buf[512], reg[12]; 215 216 r->op = OCONST; 217 r->store.fmt = fmt; 218 switch(fmt) { 219 default: 220 error("bad pointer format '%c' for *", fmt); 221 case 'c': 222 case 'C': 223 case 'b': 224 r->type = TINT; 225 ret = get1(m, addr, &cval, 1); 226 if (ret < 0) 227 error("indir: %r"); 228 r->store.u.ival = cval; 229 break; 230 case 'x': 231 case 'd': 232 case 'u': 233 case 'o': 234 case 'q': 235 case 'r': 236 r->type = TINT; 237 ret = get2(m, addr, &sval); 238 if (ret < 0) 239 error("indir: %r"); 240 r->store.u.ival = sval; 241 break; 242 case 'a': 243 case 'A': 244 case 'B': 245 case 'X': 246 case 'D': 247 case 'U': 248 case 'O': 249 case 'Q': 250 r->type = TINT; 251 ret = get4(m, addr, &ival); 252 if (ret < 0) 253 error("indir: %r"); 254 r->store.u.ival = ival; 255 break; 256 case 'V': 257 case 'W': 258 case 'Y': 259 case 'Z': 260 r->type = TINT; 261 ret = get8(m, addr, &vval); 262 if (ret < 0) 263 error("indir: %r"); 264 r->store.u.ival = vval; 265 break; 266 case 's': 267 r->type = TSTRING; 268 for(i = 0; i < sizeof(buf)-1; i++) { 269 ret = get1(m, addr, (uchar*)&buf[i], 1); 270 if (ret < 0) 271 error("indir: %r"); 272 addr++; 273 if(buf[i] == '\0') 274 break; 275 } 276 buf[i] = 0; 277 if(i == 0) 278 strcpy(buf, "(null)"); 279 r->store.u.string = strnode(buf); 280 break; 281 case 'R': 282 r->type = TSTRING; 283 assert(sizeof(Rune) == 4); 284 for(i = 0; i < sizeof(buf)-4; i += 4) { 285 ret = get4(m, addr, &ival); 286 if (ret < 0) 287 error("indir: %r"); 288 memmove(buf+i, &ival, 4); 289 addr += 4; 290 if(ival == 0) 291 break; 292 } 293 ival = 0; 294 memmove(buf+i, &ival, 4); 295 r->store.u.string = runenode((Rune*)buf); 296 break; 297 case 'i': 298 case 'I': 299 if ((*mach->das)(m, addr, fmt, buf, sizeof(buf)) < 0) 300 error("indir: %r"); 301 r->type = TSTRING; 302 r->store.fmt = 's'; 303 r->store.u.string = strnode(buf); 304 break; 305 case 'f': 306 ret = get1(m, addr, (uchar*)buf, mach->szfloat); 307 if (ret < 0) 308 error("indir: %r"); 309 mach->ftoa32(buf, sizeof(buf), (void*) buf); 310 convflt(r, buf); 311 break; 312 case 'g': 313 ret = get1(m, addr, (uchar*)buf, mach->szfloat); 314 if (ret < 0) 315 error("indir: %r"); 316 mach->ftoa32(buf, sizeof(buf), (void*) buf); 317 r->type = TSTRING; 318 r->store.u.string = strnode(buf); 319 break; 320 case 'F': 321 ret = get1(m, addr, (uchar*)buf, mach->szdouble); 322 if (ret < 0) 323 error("indir: %r"); 324 mach->ftoa64(buf, sizeof(buf), (void*) buf); 325 convflt(r, buf); 326 break; 327 case '3': /* little endian ieee 80 with hole in bytes 8&9 */ 328 ret = get1(m, addr, (uchar*)reg, 10); 329 if (ret < 0) 330 error("indir: %r"); 331 memmove(reg+10, reg+8, 2); /* open hole */ 332 memset(reg+8, 0, 2); /* fill it */ 333 leieeeftoa80(buf, sizeof(buf), reg); 334 convflt(r, buf); 335 break; 336 case '8': /* big-endian ieee 80 */ 337 ret = get1(m, addr, (uchar*)reg, 10); 338 if (ret < 0) 339 error("indir: %r"); 340 beieeeftoa80(buf, sizeof(buf), reg); 341 convflt(r, buf); 342 break; 343 case 'G': 344 ret = get1(m, addr, (uchar*)buf, mach->szdouble); 345 if (ret < 0) 346 error("indir: %r"); 347 mach->ftoa64(buf, sizeof(buf), (void*) buf); 348 r->type = TSTRING; 349 r->store.u.string = strnode(buf); 350 break; 351 } 352 } 353 354 void 355 indirreg(Regs *regs, char *name, char fmt, Node *r) 356 { 357 u64int val; 358 359 if(regs == 0) 360 error("no register set for *%s=", name); 361 362 r->op = OCONST; 363 r->store.fmt = fmt; 364 switch(fmt){ 365 default: 366 error("bad pointer format '%c' for *%s", fmt, name); 367 case 'c': 368 case 'C': 369 case 'b': 370 case 'x': 371 case 'd': 372 case 'u': 373 case 'o': 374 case 'q': 375 case 'r': 376 case 'a': 377 case 'A': 378 case 'B': 379 case 'X': 380 case 'D': 381 case 'U': 382 case 'O': 383 case 'Q': 384 case 'V': 385 case 'W': 386 case 'Y': 387 case 'Z': 388 if(rget(regs, name, &val) < 0) 389 error("reading %s: %r", name); 390 r->type = TINT; 391 r->store.u.ival = val; 392 break; 393 case 'f': 394 case 'g': 395 case 'F': 396 case '3': 397 case '8': 398 case 'G': 399 error("floating point registers not supported"); 400 break; 401 } 402 } 403 404 void 405 windir(Map *m, Node aes, Node *rval, Node *r) 406 { 407 uchar cval; 408 ushort sval; 409 Node res; 410 int ret; 411 412 if(m == 0) 413 error("no map for */@="); 414 415 if(aes.type != TINT) 416 error("bad type lhs of */@="); 417 418 expr(rval, &res); 419 420 if(m != cormap && wtflag == 0) 421 error("not in write mode"); 422 423 r->type = res.type; 424 r->store.fmt = res.store.fmt; 425 r->store = res.store; 426 427 switch(res.store.fmt) { 428 default: 429 error("bad pointer format '%c' for */@=", res.store.fmt); 430 case 'c': 431 case 'C': 432 case 'b': 433 cval = res.store.u.ival; 434 ret = put1(m, aes.store.u.ival, &cval, 1); 435 break; 436 case 'r': 437 case 'x': 438 case 'd': 439 case 'u': 440 case 'o': 441 sval = res.store.u.ival; 442 ret = put2(m, aes.store.u.ival, sval); 443 r->store.u.ival = sval; 444 break; 445 case 'a': 446 case 'A': 447 case 'B': 448 case 'X': 449 case 'D': 450 case 'U': 451 case 'O': 452 ret = put4(m, aes.store.u.ival, res.store.u.ival); 453 break; 454 case 'V': 455 case 'W': 456 case 'Y': 457 case 'Z': 458 ret = put8(m, aes.store.u.ival, res.store.u.ival); 459 break; 460 case 's': 461 case 'R': 462 ret = put1(m, aes.store.u.ival, (uchar*)res.store.u.string->string, res.store.u.string->len); 463 break; 464 } 465 if (ret < 0) 466 error("windir: %r"); 467 } 468 469 void 470 windirreg(Regs *regs, char *name, Node *rval, Node *r) 471 { 472 Node res; 473 474 if(regs == 0) 475 error("no register set for *%s=", name); 476 477 expr(rval, &res); 478 479 r->type = res.type; 480 r->store.fmt = res.store.fmt; 481 r->store = res.store; 482 483 switch(res.store.fmt){ 484 default: 485 error("bad format '%c' for *%s=", res.store.fmt, name); 486 case 'c': 487 case 'C': 488 case 'b': 489 case 'x': 490 case 'd': 491 case 'u': 492 case 'o': 493 case 'q': 494 case 'r': 495 case 'a': 496 case 'A': 497 case 'B': 498 case 'X': 499 case 'D': 500 case 'U': 501 case 'O': 502 case 'Q': 503 case 'V': 504 case 'W': 505 case 'Y': 506 case 'Z': 507 if(rput(regs, name, res.store.u.ival) < 0) 508 error("writing %s: %r", name); 509 break; 510 case 'f': 511 case 'g': 512 case 'F': 513 case '3': 514 case '8': 515 case 'G': 516 error("floating point registers not supported"); 517 break; 518 } 519 } 520 521 void 522 call(char *fn, Node *parameters, Node *local, Node *body, Node *retexp) 523 { 524 int np, i; 525 Rplace rlab; 526 Node *n, res; 527 Value *v, *f; 528 Lsym *s, *next; 529 Node *avp[Maxarg], *ava[Maxarg]; 530 531 rlab.local = 0; 532 533 na = 0; 534 flatten(avp, parameters); 535 np = na; 536 na = 0; 537 flatten(ava, local); 538 if(np != na) { 539 if(np < na) 540 error("%s: too few arguments", fn); 541 error("%s: too many arguments", fn); 542 } 543 544 rlab.tail = &rlab.local; 545 546 ret = &rlab; 547 for(i = 0; i < np; i++) { 548 n = ava[i]; 549 switch(n->op) { 550 default: 551 error("%s: %d formal not a name", fn, i); 552 case ONAME: 553 expr(avp[i], &res); 554 s = n->sym; 555 break; 556 case OINDM: 557 res.store.u.cc = avp[i]; 558 res.type = TCODE; 559 res.store.comt = 0; 560 if(n->left->op != ONAME) 561 error("%s: %d formal not a name", fn, i); 562 s = n->left->sym; 563 break; 564 } 565 if(s->v->ret == ret) 566 error("%s already declared at this scope", s->name); 567 568 v = gmalloc(sizeof(Value)); 569 v->ret = ret; 570 v->pop = s->v; 571 s->v = v; 572 v->scope = 0; 573 *(rlab.tail) = s; 574 rlab.tail = &v->scope; 575 576 v->store = res.store; 577 v->type = res.type; 578 v->set = 1; 579 } 580 581 ret->val = retexp; 582 if(setjmp(rlab.rlab) == 0) 583 execute(body); 584 585 for(s = rlab.local; s; s = next) { 586 f = s->v; 587 next = f->scope; 588 s->v = f->pop; 589 free(f); 590 } 591 }