1 /* $OpenBSD: bcode.c,v 1.47 2015/02/16 20:53:34 jca Exp $ */ 2 3 /* 4 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <err.h> 20 #include <limits.h> 21 #include <signal.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 #include "extern.h" 27 28 /* #define DEBUGGING */ 29 30 #define MAX_ARRAY_INDEX 2048 31 #define READSTACK_SIZE 8 32 33 #define NO_ELSE -2 /* -1 is EOF */ 34 #define REG_ARRAY_SIZE_SMALL (UCHAR_MAX + 1) 35 #define REG_ARRAY_SIZE_BIG (UCHAR_MAX + 1 + USHRT_MAX + 1) 36 37 struct bmachine { 38 struct stack stack; 39 u_int scale; 40 u_int obase; 41 u_int ibase; 42 size_t readsp; 43 bool extended_regs; 44 size_t reg_array_size; 45 struct stack *reg; 46 volatile sig_atomic_t interrupted; 47 struct source *readstack; 48 size_t readstack_sz; 49 }; 50 51 static struct bmachine bmachine; 52 static void sighandler(int); 53 54 static __inline int readch(void); 55 static __inline void unreadch(void); 56 static __inline char *readline(void); 57 static __inline void src_free(void); 58 59 static __inline u_int max(u_int, u_int); 60 static u_long get_ulong(struct number *); 61 62 static __inline void push_number(struct number *); 63 static __inline void push_string(char *); 64 static __inline void push(struct value *); 65 static __inline struct value *tos(void); 66 static __inline struct number *pop_number(void); 67 static __inline char *pop_string(void); 68 static __inline void clear_stack(void); 69 static __inline void print_tos(void); 70 static void pop_print(void); 71 static void pop_printn(void); 72 static __inline void print_stack(void); 73 static __inline void dup(void); 74 static void swap(void); 75 static void drop(void); 76 77 static void get_scale(void); 78 static void set_scale(void); 79 static void get_obase(void); 80 static void set_obase(void); 81 static void get_ibase(void); 82 static void set_ibase(void); 83 static void stackdepth(void); 84 static void push_scale(void); 85 static u_int count_digits(const struct number *); 86 static void num_digits(void); 87 static void to_ascii(void); 88 static void push_line(void); 89 static void comment(void); 90 static void bexec(char *); 91 static void badd(void); 92 static void bsub(void); 93 static void bmul(void); 94 static void bdiv(void); 95 static void bmod(void); 96 static void bdivmod(void); 97 static void bexp(void); 98 static bool bsqrt_stop(const BIGNUM *, const BIGNUM *, u_int *); 99 static void bsqrt(void); 100 static void not(void); 101 static void equal_numbers(void); 102 static void less_numbers(void); 103 static void lesseq_numbers(void); 104 static void equal(void); 105 static void not_equal(void); 106 static void less(void); 107 static void not_less(void); 108 static void greater(void); 109 static void not_greater(void); 110 static void not_compare(void); 111 static bool compare_numbers(enum bcode_compare, struct number *, 112 struct number *); 113 static void compare(enum bcode_compare); 114 static int readreg(void); 115 static void load(void); 116 static void store(void); 117 static void load_stack(void); 118 static void store_stack(void); 119 static void load_array(void); 120 static void store_array(void); 121 static void nop(void); 122 static void quit(void); 123 static void quitN(void); 124 static void skipN(void); 125 static void skip_until_mark(void); 126 static void parse_number(void); 127 static void unknown(void); 128 static void eval_string(char *); 129 static void eval_line(void); 130 static void eval_tos(void); 131 132 133 typedef void (*opcode_function)(void); 134 135 struct jump_entry { 136 u_char ch; 137 opcode_function f; 138 }; 139 140 static opcode_function jump_table[UCHAR_MAX]; 141 142 static const struct jump_entry jump_table_data[] = { 143 { ' ', nop }, 144 { '!', not_compare }, 145 { '#', comment }, 146 { '%', bmod }, 147 { '(', less_numbers }, 148 { '*', bmul }, 149 { '+', badd }, 150 { '-', bsub }, 151 { '.', parse_number }, 152 { '/', bdiv }, 153 { '0', parse_number }, 154 { '1', parse_number }, 155 { '2', parse_number }, 156 { '3', parse_number }, 157 { '4', parse_number }, 158 { '5', parse_number }, 159 { '6', parse_number }, 160 { '7', parse_number }, 161 { '8', parse_number }, 162 { '9', parse_number }, 163 { ':', store_array }, 164 { ';', load_array }, 165 { '<', less }, 166 { '=', equal }, 167 { '>', greater }, 168 { '?', eval_line }, 169 { 'A', parse_number }, 170 { 'B', parse_number }, 171 { 'C', parse_number }, 172 { 'D', parse_number }, 173 { 'E', parse_number }, 174 { 'F', parse_number }, 175 { 'G', equal_numbers }, 176 { 'I', get_ibase }, 177 { 'J', skipN }, 178 { 'K', get_scale }, 179 { 'L', load_stack }, 180 { 'M', nop }, 181 { 'N', not }, 182 { 'O', get_obase }, 183 { 'P', pop_print }, 184 { 'Q', quitN }, 185 { 'R', drop }, 186 { 'S', store_stack }, 187 { 'X', push_scale }, 188 { 'Z', num_digits }, 189 { '[', push_line }, 190 { '\f', nop }, 191 { '\n', nop }, 192 { '\r', nop }, 193 { '\t', nop }, 194 { '^', bexp }, 195 { '_', parse_number }, 196 { 'a', to_ascii }, 197 { 'c', clear_stack }, 198 { 'd', dup }, 199 { 'f', print_stack }, 200 { 'i', set_ibase }, 201 { 'k', set_scale }, 202 { 'l', load }, 203 { 'n', pop_printn }, 204 { 'o', set_obase }, 205 { 'p', print_tos }, 206 { 'q', quit }, 207 { 'r', swap }, 208 { 's', store }, 209 { 'v', bsqrt }, 210 { 'x', eval_tos }, 211 { 'z', stackdepth }, 212 { '{', lesseq_numbers }, 213 { '~', bdivmod } 214 }; 215 216 #define JUMP_TABLE_DATA_SIZE \ 217 (sizeof(jump_table_data)/sizeof(jump_table_data[0])) 218 219 /* ARGSUSED */ 220 static void 221 sighandler(int ignored) 222 { 223 bmachine.interrupted = true; 224 } 225 226 void 227 init_bmachine(bool extended_registers) 228 { 229 int i; 230 231 bmachine.extended_regs = extended_registers; 232 bmachine.reg_array_size = bmachine.extended_regs ? 233 REG_ARRAY_SIZE_BIG : REG_ARRAY_SIZE_SMALL; 234 235 bmachine.reg = calloc(bmachine.reg_array_size, 236 sizeof(bmachine.reg[0])); 237 if (bmachine.reg == NULL) 238 err(1, NULL); 239 240 for (i = 0; i < UCHAR_MAX; i++) 241 jump_table[i] = unknown; 242 for (i = 0; i < JUMP_TABLE_DATA_SIZE; i++) 243 jump_table[jump_table_data[i].ch] = jump_table_data[i].f; 244 245 stack_init(&bmachine.stack); 246 247 for (i = 0; i < bmachine.reg_array_size; i++) 248 stack_init(&bmachine.reg[i]); 249 250 bmachine.readstack_sz = READSTACK_SIZE; 251 bmachine.readstack = calloc(sizeof(struct source), 252 bmachine.readstack_sz); 253 if (bmachine.readstack == NULL) 254 err(1, NULL); 255 bmachine.obase = bmachine.ibase = 10; 256 (void)signal(SIGINT, sighandler); 257 } 258 259 u_int 260 bmachine_scale(void) 261 { 262 return bmachine.scale; 263 } 264 265 /* Reset the things needed before processing a (new) file */ 266 void 267 reset_bmachine(struct source *src) 268 { 269 bmachine.readsp = 0; 270 bmachine.readstack[0] = *src; 271 } 272 273 static __inline int 274 readch(void) 275 { 276 struct source *src = &bmachine.readstack[bmachine.readsp]; 277 278 return src->vtable->readchar(src); 279 } 280 281 static __inline void 282 unreadch(void) 283 { 284 struct source *src = &bmachine.readstack[bmachine.readsp]; 285 286 src->vtable->unreadchar(src); 287 } 288 289 static __inline char * 290 readline(void) 291 { 292 struct source *src = &bmachine.readstack[bmachine.readsp]; 293 294 return src->vtable->readline(src); 295 } 296 297 static __inline void 298 src_free(void) 299 { 300 struct source *src = &bmachine.readstack[bmachine.readsp]; 301 302 src->vtable->free(src); 303 } 304 305 #ifdef DEBUGGING 306 void 307 pn(const char *str, const struct number *n) 308 { 309 char *p = BN_bn2dec(n->number); 310 if (p == NULL) 311 err(1, "BN_bn2dec failed"); 312 (void)fputs(str, stderr); 313 (void)fprintf(stderr, " %s (%u)\n" , p, n->scale); 314 OPENSSL_free(p); 315 } 316 317 void 318 pbn(const char *str, const BIGNUM *n) 319 { 320 char *p = BN_bn2dec(n); 321 if (p == NULL) 322 err(1, "BN_bn2dec failed"); 323 (void)fputs(str, stderr); 324 (void)fprintf(stderr, " %s\n", p); 325 OPENSSL_free(p); 326 } 327 328 #endif 329 330 static __inline u_int 331 max(u_int a, u_int b) 332 { 333 return a > b ? a : b; 334 } 335 336 static unsigned long factors[] = { 337 0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 338 100000000, 1000000000 339 }; 340 341 void 342 scale_number(BIGNUM *n, int s) 343 { 344 int abs_scale; 345 346 if (s == 0) 347 return; 348 349 abs_scale = s > 0 ? s : -s; 350 351 if (abs_scale < sizeof(factors)/sizeof(factors[0])) { 352 if (s > 0) 353 bn_check(BN_mul_word(n, factors[abs_scale])); 354 else 355 (void)BN_div_word(n, factors[abs_scale]); 356 } else { 357 BIGNUM *a, *p; 358 BN_CTX *ctx; 359 360 a = BN_new(); 361 bn_checkp(a); 362 p = BN_new(); 363 bn_checkp(p); 364 ctx = BN_CTX_new(); 365 bn_checkp(ctx); 366 367 bn_check(BN_set_word(a, 10)); 368 bn_check(BN_set_word(p, abs_scale)); 369 bn_check(BN_exp(a, a, p, ctx)); 370 if (s > 0) 371 bn_check(BN_mul(n, n, a, ctx)); 372 else 373 bn_check(BN_div(n, NULL, n, a, ctx)); 374 BN_CTX_free(ctx); 375 BN_free(a); 376 BN_free(p); 377 } 378 } 379 380 void 381 split_number(const struct number *n, BIGNUM *i, BIGNUM *f) 382 { 383 u_long rem; 384 385 bn_checkp(BN_copy(i, n->number)); 386 387 if (n->scale == 0 && f != NULL) 388 bn_check(BN_zero(f)); 389 else if (n->scale < sizeof(factors)/sizeof(factors[0])) { 390 rem = BN_div_word(i, factors[n->scale]); 391 if (f != NULL) 392 bn_check(BN_set_word(f, rem)); 393 } else { 394 BIGNUM *a, *p; 395 BN_CTX *ctx; 396 397 a = BN_new(); 398 bn_checkp(a); 399 p = BN_new(); 400 bn_checkp(p); 401 ctx = BN_CTX_new(); 402 bn_checkp(ctx); 403 404 bn_check(BN_set_word(a, 10)); 405 bn_check(BN_set_word(p, n->scale)); 406 bn_check(BN_exp(a, a, p, ctx)); 407 bn_check(BN_div(i, f, n->number, a, ctx)); 408 BN_CTX_free(ctx); 409 BN_free(a); 410 BN_free(p); 411 } 412 } 413 414 void 415 normalize(struct number *n, u_int s) 416 { 417 scale_number(n->number, s - n->scale); 418 n->scale = s; 419 } 420 421 static u_long 422 get_ulong(struct number *n) 423 { 424 normalize(n, 0); 425 return BN_get_word(n->number); 426 } 427 428 void 429 negate(struct number *n) 430 { 431 BN_set_negative(n->number, !BN_is_negative(n->number)); 432 } 433 434 static __inline void 435 push_number(struct number *n) 436 { 437 stack_pushnumber(&bmachine.stack, n); 438 } 439 440 static __inline void 441 push_string(char *string) 442 { 443 stack_pushstring(&bmachine.stack, string); 444 } 445 446 static __inline void 447 push(struct value *v) 448 { 449 stack_push(&bmachine.stack, v); 450 } 451 452 static __inline struct value * 453 tos(void) 454 { 455 return stack_tos(&bmachine.stack); 456 } 457 458 static __inline struct value * 459 pop(void) 460 { 461 return stack_pop(&bmachine.stack); 462 } 463 464 static __inline struct number * 465 pop_number(void) 466 { 467 return stack_popnumber(&bmachine.stack); 468 } 469 470 static __inline char * 471 pop_string(void) 472 { 473 return stack_popstring(&bmachine.stack); 474 } 475 476 static __inline void 477 clear_stack(void) 478 { 479 stack_clear(&bmachine.stack); 480 } 481 482 static __inline void 483 print_stack(void) 484 { 485 stack_print(stdout, &bmachine.stack, "", bmachine.obase); 486 } 487 488 static __inline void 489 print_tos(void) 490 { 491 struct value *value = tos(); 492 if (value != NULL) { 493 print_value(stdout, value, "", bmachine.obase); 494 (void)putchar('\n'); 495 } 496 else 497 warnx("stack empty"); 498 } 499 500 static void 501 pop_print(void) 502 { 503 struct value *value = pop(); 504 505 if (value != NULL) { 506 switch (value->type) { 507 case BCODE_NONE: 508 break; 509 case BCODE_NUMBER: 510 normalize(value->u.num, 0); 511 print_ascii(stdout, value->u.num); 512 (void)fflush(stdout); 513 break; 514 case BCODE_STRING: 515 (void)fputs(value->u.string, stdout); 516 (void)fflush(stdout); 517 break; 518 } 519 stack_free_value(value); 520 } 521 } 522 523 static void 524 pop_printn(void) 525 { 526 struct value *value = pop(); 527 528 if (value != NULL) { 529 print_value(stdout, value, "", bmachine.obase); 530 (void)fflush(stdout); 531 stack_free_value(value); 532 } 533 } 534 535 static __inline void 536 dup(void) 537 { 538 stack_dup(&bmachine.stack); 539 } 540 541 static void 542 swap(void) 543 { 544 stack_swap(&bmachine.stack); 545 } 546 547 static void 548 drop(void) 549 { 550 struct value *v = pop(); 551 if (v != NULL) 552 stack_free_value(v); 553 } 554 555 static void 556 get_scale(void) 557 { 558 struct number *n; 559 560 n = new_number(); 561 bn_check(BN_set_word(n->number, bmachine.scale)); 562 push_number(n); 563 } 564 565 static void 566 set_scale(void) 567 { 568 struct number *n; 569 u_long scale; 570 571 n = pop_number(); 572 if (n != NULL) { 573 if (BN_is_negative(n->number)) 574 warnx("scale must be a nonnegative number"); 575 else { 576 scale = get_ulong(n); 577 if (scale != BN_MASK2 && scale <= UINT_MAX) 578 bmachine.scale = (u_int)scale; 579 else 580 warnx("scale too large"); 581 } 582 free_number(n); 583 } 584 } 585 586 static void 587 get_obase(void) 588 { 589 struct number *n; 590 591 n = new_number(); 592 bn_check(BN_set_word(n->number, bmachine.obase)); 593 push_number(n); 594 } 595 596 static void 597 set_obase(void) 598 { 599 struct number *n; 600 u_long base; 601 602 n = pop_number(); 603 if (n != NULL) { 604 base = get_ulong(n); 605 if (base != BN_MASK2 && base > 1 && base <= UINT_MAX) 606 bmachine.obase = (u_int)base; 607 else 608 warnx("output base must be a number greater than 1"); 609 free_number(n); 610 } 611 } 612 613 static void 614 get_ibase(void) 615 { 616 struct number *n; 617 618 n = new_number(); 619 bn_check(BN_set_word(n->number, bmachine.ibase)); 620 push_number(n); 621 } 622 623 static void 624 set_ibase(void) 625 { 626 struct number *n; 627 u_long base; 628 629 n = pop_number(); 630 if (n != NULL) { 631 base = get_ulong(n); 632 if (base != BN_MASK2 && 2 <= base && base <= 16) 633 bmachine.ibase = (u_int)base; 634 else 635 warnx("input base must be a number between 2 and 16 " 636 "(inclusive)"); 637 free_number(n); 638 } 639 } 640 641 static void 642 stackdepth(void) 643 { 644 size_t i; 645 struct number *n; 646 647 i = stack_size(&bmachine.stack); 648 n = new_number(); 649 bn_check(BN_set_word(n->number, i)); 650 push_number(n); 651 } 652 653 static void 654 push_scale(void) 655 { 656 struct value *value; 657 u_int scale = 0; 658 struct number *n; 659 660 661 value = pop(); 662 if (value != NULL) { 663 switch (value->type) { 664 case BCODE_NONE: 665 return; 666 case BCODE_NUMBER: 667 scale = value->u.num->scale; 668 break; 669 case BCODE_STRING: 670 break; 671 } 672 stack_free_value(value); 673 n = new_number(); 674 bn_check(BN_set_word(n->number, scale)); 675 push_number(n); 676 } 677 } 678 679 static u_int 680 count_digits(const struct number *n) 681 { 682 struct number *int_part, *fract_part; 683 u_int i; 684 685 if (BN_is_zero(n->number)) 686 return n->scale ? n->scale : 1; 687 688 int_part = new_number(); 689 fract_part = new_number(); 690 fract_part->scale = n->scale; 691 split_number(n, int_part->number, fract_part->number); 692 693 i = 0; 694 while (!BN_is_zero(int_part->number)) { 695 (void)BN_div_word(int_part->number, 10); 696 i++; 697 } 698 free_number(int_part); 699 free_number(fract_part); 700 return i + n->scale; 701 } 702 703 static void 704 num_digits(void) 705 { 706 struct value *value; 707 size_t digits; 708 struct number *n = NULL; 709 710 value = pop(); 711 if (value != NULL) { 712 switch (value->type) { 713 case BCODE_NONE: 714 return; 715 case BCODE_NUMBER: 716 digits = count_digits(value->u.num); 717 n = new_number(); 718 bn_check(BN_set_word(n->number, digits)); 719 break; 720 case BCODE_STRING: 721 digits = strlen(value->u.string); 722 n = new_number(); 723 bn_check(BN_set_word(n->number, digits)); 724 break; 725 } 726 stack_free_value(value); 727 push_number(n); 728 } 729 } 730 731 static void 732 to_ascii(void) 733 { 734 char str[2]; 735 struct value *value; 736 struct number *n; 737 738 value = pop(); 739 if (value != NULL) { 740 str[1] = '\0'; 741 switch (value->type) { 742 case BCODE_NONE: 743 return; 744 case BCODE_NUMBER: 745 n = value->u.num; 746 normalize(n, 0); 747 if (BN_num_bits(n->number) > 8) 748 bn_check(BN_mask_bits(n->number, 8)); 749 str[0] = (char)BN_get_word(n->number); 750 break; 751 case BCODE_STRING: 752 str[0] = value->u.string[0]; 753 break; 754 } 755 stack_free_value(value); 756 push_string(bstrdup(str)); 757 } 758 } 759 760 static int 761 readreg(void) 762 { 763 int idx, ch1, ch2; 764 765 idx = readch(); 766 if (idx == 0xff && bmachine.extended_regs) { 767 ch1 = readch(); 768 ch2 = readch(); 769 if (ch1 == EOF || ch2 == EOF) { 770 warnx("unexpected eof"); 771 idx = -1; 772 } else 773 idx = (ch1 << 8) + ch2 + UCHAR_MAX + 1; 774 } 775 if (idx < 0 || idx >= bmachine.reg_array_size) { 776 warnx("internal error: reg num = %d", idx); 777 idx = -1; 778 } 779 return idx; 780 } 781 782 static void 783 load(void) 784 { 785 int idx; 786 struct value *v, copy; 787 struct number *n; 788 789 idx = readreg(); 790 if (idx >= 0) { 791 v = stack_tos(&bmachine.reg[idx]); 792 if (v == NULL) { 793 n = new_number(); 794 bn_check(BN_zero(n->number)); 795 push_number(n); 796 } else 797 push(stack_dup_value(v, ©)); 798 } 799 } 800 801 static void 802 store(void) 803 { 804 int idx; 805 struct value *val; 806 807 idx = readreg(); 808 if (idx >= 0) { 809 val = pop(); 810 if (val == NULL) { 811 return; 812 } 813 stack_set_tos(&bmachine.reg[idx], val); 814 } 815 } 816 817 static void 818 load_stack(void) 819 { 820 int idx; 821 struct stack *stack; 822 struct value *value; 823 824 idx = readreg(); 825 if (idx >= 0) { 826 stack = &bmachine.reg[idx]; 827 value = NULL; 828 if (stack_size(stack) > 0) { 829 value = stack_pop(stack); 830 } 831 if (value != NULL) 832 push(value); 833 else 834 warnx("stack register '%c' (0%o) is empty", 835 idx, idx); 836 } 837 } 838 839 static void 840 store_stack(void) 841 { 842 int idx; 843 struct value *value; 844 845 idx = readreg(); 846 if (idx >= 0) { 847 value = pop(); 848 if (value == NULL) 849 return; 850 stack_push(&bmachine.reg[idx], value); 851 } 852 } 853 854 static void 855 load_array(void) 856 { 857 int reg; 858 struct number *inumber, *n; 859 u_long idx; 860 struct stack *stack; 861 struct value *v, copy; 862 863 reg = readreg(); 864 if (reg >= 0) { 865 inumber = pop_number(); 866 if (inumber == NULL) 867 return; 868 idx = get_ulong(inumber); 869 if (BN_is_negative(inumber->number)) 870 warnx("negative idx"); 871 else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) 872 warnx("idx too big"); 873 else { 874 stack = &bmachine.reg[reg]; 875 v = frame_retrieve(stack, idx); 876 if (v == NULL || v->type == BCODE_NONE) { 877 n = new_number(); 878 bn_check(BN_zero(n->number)); 879 push_number(n); 880 } 881 else 882 push(stack_dup_value(v, ©)); 883 } 884 free_number(inumber); 885 } 886 } 887 888 static void 889 store_array(void) 890 { 891 int reg; 892 struct number *inumber; 893 u_long idx; 894 struct value *value; 895 struct stack *stack; 896 897 reg = readreg(); 898 if (reg >= 0) { 899 inumber = pop_number(); 900 if (inumber == NULL) 901 return; 902 value = pop(); 903 if (value == NULL) { 904 free_number(inumber); 905 return; 906 } 907 idx = get_ulong(inumber); 908 if (BN_is_negative(inumber->number)) { 909 warnx("negative idx"); 910 stack_free_value(value); 911 } else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) { 912 warnx("idx too big"); 913 stack_free_value(value); 914 } else { 915 stack = &bmachine.reg[reg]; 916 frame_assign(stack, idx, value); 917 } 918 free_number(inumber); 919 } 920 } 921 922 static void 923 push_line(void) 924 { 925 push_string(read_string(&bmachine.readstack[bmachine.readsp])); 926 } 927 928 static void 929 comment(void) 930 { 931 free(readline()); 932 } 933 934 static void 935 bexec(char *line) 936 { 937 (void)system(line); 938 free(line); 939 } 940 941 static void 942 badd(void) 943 { 944 struct number *a, *b; 945 struct number *r; 946 947 a = pop_number(); 948 if (a == NULL) { 949 return; 950 } 951 b = pop_number(); 952 if (b == NULL) { 953 push_number(a); 954 return; 955 } 956 957 r = new_number(); 958 r->scale = max(a->scale, b->scale); 959 if (r->scale > a->scale) 960 normalize(a, r->scale); 961 else if (r->scale > b->scale) 962 normalize(b, r->scale); 963 bn_check(BN_add(r->number, a->number, b->number)); 964 push_number(r); 965 free_number(a); 966 free_number(b); 967 } 968 969 static void 970 bsub(void) 971 { 972 struct number *a, *b; 973 struct number *r; 974 975 a = pop_number(); 976 if (a == NULL) { 977 return; 978 } 979 b = pop_number(); 980 if (b == NULL) { 981 push_number(a); 982 return; 983 } 984 985 r = new_number(); 986 987 r->scale = max(a->scale, b->scale); 988 if (r->scale > a->scale) 989 normalize(a, r->scale); 990 else if (r->scale > b->scale) 991 normalize(b, r->scale); 992 bn_check(BN_sub(r->number, b->number, a->number)); 993 push_number(r); 994 free_number(a); 995 free_number(b); 996 } 997 998 void 999 bmul_number(struct number *r, struct number *a, struct number *b, u_int scale) 1000 { 1001 BN_CTX *ctx; 1002 1003 /* Create copies of the scales, since r might be equal to a or b */ 1004 u_int ascale = a->scale; 1005 u_int bscale = b->scale; 1006 u_int rscale = ascale + bscale; 1007 1008 ctx = BN_CTX_new(); 1009 bn_checkp(ctx); 1010 bn_check(BN_mul(r->number, a->number, b->number, ctx)); 1011 BN_CTX_free(ctx); 1012 1013 r->scale = rscale; 1014 if (rscale > bmachine.scale && rscale > ascale && rscale > bscale) 1015 normalize(r, max(scale, max(ascale, bscale))); 1016 } 1017 1018 static void 1019 bmul(void) 1020 { 1021 struct number *a, *b; 1022 struct number *r; 1023 1024 a = pop_number(); 1025 if (a == NULL) { 1026 return; 1027 } 1028 b = pop_number(); 1029 if (b == NULL) { 1030 push_number(a); 1031 return; 1032 } 1033 1034 r = new_number(); 1035 bmul_number(r, a, b, bmachine.scale); 1036 1037 push_number(r); 1038 free_number(a); 1039 free_number(b); 1040 } 1041 1042 static void 1043 bdiv(void) 1044 { 1045 struct number *a, *b; 1046 struct number *r; 1047 u_int scale; 1048 BN_CTX *ctx; 1049 1050 a = pop_number(); 1051 if (a == NULL) { 1052 return; 1053 } 1054 b = pop_number(); 1055 if (b == NULL) { 1056 push_number(a); 1057 return; 1058 } 1059 1060 r = new_number(); 1061 r->scale = bmachine.scale; 1062 scale = max(a->scale, b->scale); 1063 1064 if (BN_is_zero(a->number)) 1065 warnx("divide by zero"); 1066 else { 1067 normalize(a, scale); 1068 normalize(b, scale + r->scale); 1069 1070 ctx = BN_CTX_new(); 1071 bn_checkp(ctx); 1072 bn_check(BN_div(r->number, NULL, b->number, a->number, ctx)); 1073 BN_CTX_free(ctx); 1074 } 1075 push_number(r); 1076 free_number(a); 1077 free_number(b); 1078 } 1079 1080 static void 1081 bmod(void) 1082 { 1083 struct number *a, *b; 1084 struct number *r; 1085 u_int scale; 1086 BN_CTX *ctx; 1087 1088 a = pop_number(); 1089 if (a == NULL) { 1090 return; 1091 } 1092 b = pop_number(); 1093 if (b == NULL) { 1094 push_number(a); 1095 return; 1096 } 1097 1098 r = new_number(); 1099 scale = max(a->scale, b->scale); 1100 r->scale = max(b->scale, a->scale + bmachine.scale); 1101 1102 if (BN_is_zero(a->number)) 1103 warnx("remainder by zero"); 1104 else { 1105 normalize(a, scale); 1106 normalize(b, scale + bmachine.scale); 1107 1108 ctx = BN_CTX_new(); 1109 bn_checkp(ctx); 1110 bn_check(BN_mod(r->number, b->number, a->number, ctx)); 1111 BN_CTX_free(ctx); 1112 } 1113 push_number(r); 1114 free_number(a); 1115 free_number(b); 1116 } 1117 1118 static void 1119 bdivmod(void) 1120 { 1121 struct number *a, *b; 1122 struct number *rdiv, *rmod; 1123 u_int scale; 1124 BN_CTX *ctx; 1125 1126 a = pop_number(); 1127 if (a == NULL) { 1128 return; 1129 } 1130 b = pop_number(); 1131 if (b == NULL) { 1132 push_number(a); 1133 return; 1134 } 1135 1136 rdiv = new_number(); 1137 rmod = new_number(); 1138 rdiv->scale = bmachine.scale; 1139 rmod->scale = max(b->scale, a->scale + bmachine.scale); 1140 scale = max(a->scale, b->scale); 1141 1142 if (BN_is_zero(a->number)) 1143 warnx("divide by zero"); 1144 else { 1145 normalize(a, scale); 1146 normalize(b, scale + bmachine.scale); 1147 1148 ctx = BN_CTX_new(); 1149 bn_checkp(ctx); 1150 bn_check(BN_div(rdiv->number, rmod->number, 1151 b->number, a->number, ctx)); 1152 BN_CTX_free(ctx); 1153 } 1154 push_number(rdiv); 1155 push_number(rmod); 1156 free_number(a); 1157 free_number(b); 1158 } 1159 1160 static void 1161 bexp(void) 1162 { 1163 struct number *a, *p; 1164 struct number *r; 1165 bool neg; 1166 u_int rscale; 1167 1168 p = pop_number(); 1169 if (p == NULL) { 1170 return; 1171 } 1172 a = pop_number(); 1173 if (a == NULL) { 1174 push_number(p); 1175 return; 1176 } 1177 1178 if (p->scale != 0) { 1179 BIGNUM *i, *f; 1180 i = BN_new(); 1181 bn_checkp(i); 1182 f = BN_new(); 1183 bn_checkp(f); 1184 split_number(p, i, f); 1185 if (!BN_is_zero(f)) 1186 warnx("Runtime warning: non-zero fractional part in exponent"); 1187 BN_free(i); 1188 BN_free(f); 1189 } 1190 1191 normalize(p, 0); 1192 1193 neg = false; 1194 if (BN_is_negative(p->number)) { 1195 neg = true; 1196 negate(p); 1197 rscale = bmachine.scale; 1198 } else { 1199 /* Posix bc says min(a.scale * b, max(a.scale, scale) */ 1200 u_long b; 1201 u_int m; 1202 1203 b = BN_get_word(p->number); 1204 m = max(a->scale, bmachine.scale); 1205 rscale = a->scale * (u_int)b; 1206 if (rscale > m || (a->scale > 0 && (b == BN_MASK2 || 1207 b > UINT_MAX))) 1208 rscale = m; 1209 } 1210 1211 if (BN_is_zero(p->number)) { 1212 r = new_number(); 1213 bn_check(BN_one(r->number)); 1214 normalize(r, rscale); 1215 } else { 1216 u_int ascale, mscale; 1217 1218 ascale = a->scale; 1219 while (!BN_is_bit_set(p->number, 0)) { 1220 ascale *= 2; 1221 bmul_number(a, a, a, ascale); 1222 bn_check(BN_rshift1(p->number, p->number)); 1223 } 1224 1225 r = dup_number(a); 1226 bn_check(BN_rshift1(p->number, p->number)); 1227 1228 mscale = ascale; 1229 while (!BN_is_zero(p->number)) { 1230 ascale *= 2; 1231 bmul_number(a, a, a, ascale); 1232 if (BN_is_bit_set(p->number, 0)) { 1233 mscale += ascale; 1234 bmul_number(r, r, a, mscale); 1235 } 1236 bn_check(BN_rshift1(p->number, p->number)); 1237 } 1238 1239 if (neg) { 1240 BN_CTX *ctx; 1241 BIGNUM *one; 1242 1243 one = BN_new(); 1244 bn_checkp(one); 1245 bn_check(BN_one(one)); 1246 ctx = BN_CTX_new(); 1247 bn_checkp(ctx); 1248 scale_number(one, r->scale + rscale); 1249 1250 if (BN_is_zero(r->number)) 1251 warnx("divide by zero"); 1252 else 1253 bn_check(BN_div(r->number, NULL, one, 1254 r->number, ctx)); 1255 BN_free(one); 1256 BN_CTX_free(ctx); 1257 r->scale = rscale; 1258 } else 1259 normalize(r, rscale); 1260 } 1261 push_number(r); 1262 free_number(a); 1263 free_number(p); 1264 } 1265 1266 static bool 1267 bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount) 1268 { 1269 BIGNUM *r; 1270 bool ret; 1271 1272 r = BN_new(); 1273 bn_checkp(r); 1274 bn_check(BN_sub(r, x, y)); 1275 if (BN_is_one(r)) 1276 (*onecount)++; 1277 ret = BN_is_zero(r); 1278 BN_free(r); 1279 return ret || *onecount > 1; 1280 } 1281 1282 static void 1283 bsqrt(void) 1284 { 1285 struct number *n; 1286 struct number *r; 1287 BIGNUM *x, *y; 1288 u_int scale, onecount; 1289 BN_CTX *ctx; 1290 1291 onecount = 0; 1292 n = pop_number(); 1293 if (n == NULL) { 1294 return; 1295 } 1296 if (BN_is_zero(n->number)) { 1297 r = new_number(); 1298 push_number(r); 1299 } else if (BN_is_negative(n->number)) 1300 warnx("square root of negative number"); 1301 else { 1302 scale = max(bmachine.scale, n->scale); 1303 normalize(n, 2*scale); 1304 x = BN_dup(n->number); 1305 bn_checkp(x); 1306 bn_check(BN_rshift(x, x, BN_num_bits(x)/2)); 1307 y = BN_new(); 1308 bn_checkp(y); 1309 ctx = BN_CTX_new(); 1310 bn_checkp(ctx); 1311 for (;;) { 1312 bn_checkp(BN_copy(y, x)); 1313 bn_check(BN_div(x, NULL, n->number, x, ctx)); 1314 bn_check(BN_add(x, x, y)); 1315 bn_check(BN_rshift1(x, x)); 1316 if (bsqrt_stop(x, y, &onecount)) 1317 break; 1318 } 1319 r = bmalloc(sizeof(*r)); 1320 r->scale = scale; 1321 r->number = y; 1322 BN_free(x); 1323 BN_CTX_free(ctx); 1324 push_number(r); 1325 } 1326 1327 free_number(n); 1328 } 1329 1330 static void 1331 not(void) 1332 { 1333 struct number *a; 1334 1335 a = pop_number(); 1336 if (a == NULL) { 1337 return; 1338 } 1339 a->scale = 0; 1340 bn_check(BN_set_word(a->number, BN_get_word(a->number) ? 0 : 1)); 1341 push_number(a); 1342 } 1343 1344 static void 1345 equal(void) 1346 { 1347 compare(BCODE_EQUAL); 1348 } 1349 1350 static void 1351 equal_numbers(void) 1352 { 1353 struct number *a, *b, *r; 1354 1355 a = pop_number(); 1356 if (a == NULL) { 1357 return; 1358 } 1359 b = pop_number(); 1360 if (b == NULL) { 1361 push_number(a); 1362 return; 1363 } 1364 r = new_number(); 1365 bn_check(BN_set_word(r->number, 1366 compare_numbers(BCODE_EQUAL, a, b) ? 1 : 0)); 1367 push_number(r); 1368 } 1369 1370 static void 1371 less_numbers(void) 1372 { 1373 struct number *a, *b, *r; 1374 1375 a = pop_number(); 1376 if (a == NULL) { 1377 return; 1378 } 1379 b = pop_number(); 1380 if (b == NULL) { 1381 push_number(a); 1382 return; 1383 } 1384 r = new_number(); 1385 bn_check(BN_set_word(r->number, 1386 compare_numbers(BCODE_LESS, a, b) ? 1 : 0)); 1387 push_number(r); 1388 } 1389 1390 static void 1391 lesseq_numbers(void) 1392 { 1393 struct number *a, *b, *r; 1394 1395 a = pop_number(); 1396 if (a == NULL) { 1397 return; 1398 } 1399 b = pop_number(); 1400 if (b == NULL) { 1401 push_number(a); 1402 return; 1403 } 1404 r = new_number(); 1405 bn_check(BN_set_word(r->number, 1406 compare_numbers(BCODE_NOT_GREATER, a, b) ? 1 : 0)); 1407 push_number(r); 1408 } 1409 1410 static void 1411 not_equal(void) 1412 { 1413 compare(BCODE_NOT_EQUAL); 1414 } 1415 1416 static void 1417 less(void) 1418 { 1419 compare(BCODE_LESS); 1420 } 1421 1422 static void 1423 not_compare(void) 1424 { 1425 switch (readch()) { 1426 case '<': 1427 not_less(); 1428 break; 1429 case '>': 1430 not_greater(); 1431 break; 1432 case '=': 1433 not_equal(); 1434 break; 1435 default: 1436 unreadch(); 1437 bexec(readline()); 1438 break; 1439 } 1440 } 1441 1442 static void 1443 not_less(void) 1444 { 1445 compare(BCODE_NOT_LESS); 1446 } 1447 1448 static void 1449 greater(void) 1450 { 1451 compare(BCODE_GREATER); 1452 } 1453 1454 static void 1455 not_greater(void) 1456 { 1457 compare(BCODE_NOT_GREATER); 1458 } 1459 1460 static bool 1461 compare_numbers(enum bcode_compare type, struct number *a, struct number *b) 1462 { 1463 u_int scale; 1464 int cmp; 1465 1466 scale = max(a->scale, b->scale); 1467 1468 if (scale > a->scale) 1469 normalize(a, scale); 1470 else if (scale > b->scale) 1471 normalize(b, scale); 1472 1473 cmp = BN_cmp(a->number, b->number); 1474 1475 free_number(a); 1476 free_number(b); 1477 1478 switch (type) { 1479 case BCODE_EQUAL: 1480 return cmp == 0; 1481 case BCODE_NOT_EQUAL: 1482 return cmp != 0; 1483 case BCODE_LESS: 1484 return cmp < 0; 1485 case BCODE_NOT_LESS: 1486 return cmp >= 0; 1487 case BCODE_GREATER: 1488 return cmp > 0; 1489 case BCODE_NOT_GREATER: 1490 return cmp <= 0; 1491 } 1492 return false; 1493 } 1494 1495 static void 1496 compare(enum bcode_compare type) 1497 { 1498 int idx, elseidx; 1499 struct number *a, *b; 1500 bool ok; 1501 struct value *v; 1502 1503 elseidx = NO_ELSE; 1504 idx = readreg(); 1505 if (readch() == 'e') 1506 elseidx = readreg(); 1507 else 1508 unreadch(); 1509 1510 a = pop_number(); 1511 if (a == NULL) 1512 return; 1513 b = pop_number(); 1514 if (b == NULL) { 1515 push_number(a); 1516 return; 1517 } 1518 1519 ok = compare_numbers(type, a, b); 1520 1521 if (!ok && elseidx != NO_ELSE) 1522 idx = elseidx; 1523 1524 if (idx >= 0 && (ok || (!ok && elseidx != NO_ELSE))) { 1525 v = stack_tos(&bmachine.reg[idx]); 1526 if (v == NULL) 1527 warnx("register '%c' (0%o) is empty", idx, idx); 1528 else { 1529 switch(v->type) { 1530 case BCODE_NONE: 1531 warnx("register '%c' (0%o) is empty", idx, idx); 1532 break; 1533 case BCODE_NUMBER: 1534 warn("eval called with non-string argument"); 1535 break; 1536 case BCODE_STRING: 1537 eval_string(bstrdup(v->u.string)); 1538 break; 1539 } 1540 } 1541 } 1542 } 1543 1544 1545 static void 1546 nop(void) 1547 { 1548 } 1549 1550 static void 1551 quit(void) 1552 { 1553 if (bmachine.readsp < 2) 1554 exit(0); 1555 src_free(); 1556 bmachine.readsp--; 1557 src_free(); 1558 bmachine.readsp--; 1559 } 1560 1561 static void 1562 quitN(void) 1563 { 1564 struct number *n; 1565 u_long i; 1566 1567 n = pop_number(); 1568 if (n == NULL) 1569 return; 1570 i = get_ulong(n); 1571 free_number(n); 1572 if (i == BN_MASK2 || i == 0) 1573 warnx("Q command requires a number >= 1"); 1574 else if (bmachine.readsp < i) 1575 warnx("Q command argument exceeded string execution depth"); 1576 else { 1577 while (i-- > 0) { 1578 src_free(); 1579 bmachine.readsp--; 1580 } 1581 } 1582 } 1583 1584 static void 1585 skipN(void) 1586 { 1587 struct number *n; 1588 u_long i; 1589 1590 n = pop_number(); 1591 if (n == NULL) 1592 return; 1593 i = get_ulong(n); 1594 if (i == BN_MASK2) 1595 warnx("J command requires a number >= 0"); 1596 else if (i > 0 && bmachine.readsp < i) 1597 warnx("J command argument exceeded string execution depth"); 1598 else { 1599 while (i-- > 0) { 1600 src_free(); 1601 bmachine.readsp--; 1602 } 1603 skip_until_mark(); 1604 } 1605 } 1606 1607 static void 1608 skip_until_mark(void) 1609 { 1610 int ch; 1611 1612 for (;;) { 1613 ch = readch(); 1614 switch (ch) { 1615 case 'M': 1616 return; 1617 case EOF: 1618 errx(1, "mark not found"); 1619 return; 1620 case 'l': 1621 case 'L': 1622 case 's': 1623 case 'S': 1624 case ':': 1625 case ';': 1626 case '<': 1627 case '>': 1628 case '=': 1629 (void)readreg(); 1630 if (readch() == 'e') 1631 (void)readreg(); 1632 else 1633 unreadch(); 1634 break; 1635 case '[': 1636 free(read_string(&bmachine.readstack[bmachine.readsp])); 1637 break; 1638 case '!': 1639 switch (ch = readch()) { 1640 case '<': 1641 case '>': 1642 case '=': 1643 (void)readreg(); 1644 if (readch() == 'e') 1645 (void)readreg(); 1646 else 1647 unreadch(); 1648 break; 1649 default: 1650 free(readline()); 1651 break; 1652 } 1653 break; 1654 default: 1655 break; 1656 } 1657 } 1658 } 1659 1660 static void 1661 parse_number(void) 1662 { 1663 unreadch(); 1664 push_number(readnumber(&bmachine.readstack[bmachine.readsp], 1665 bmachine.ibase)); 1666 } 1667 1668 static void 1669 unknown(void) 1670 { 1671 int ch = bmachine.readstack[bmachine.readsp].lastchar; 1672 warnx("%c (0%o) is unimplemented", ch, ch); 1673 } 1674 1675 static void 1676 eval_string(char *p) 1677 { 1678 int ch; 1679 1680 if (bmachine.readsp > 0) { 1681 /* Check for tail call. Do not recurse in that case. */ 1682 ch = readch(); 1683 if (ch == EOF) { 1684 src_free(); 1685 src_setstring(&bmachine.readstack[bmachine.readsp], p); 1686 return; 1687 } else 1688 unreadch(); 1689 } 1690 if (bmachine.readsp == bmachine.readstack_sz - 1) { 1691 size_t newsz = bmachine.readstack_sz * 2; 1692 struct source *stack; 1693 stack = reallocarray(bmachine.readstack, newsz, 1694 sizeof(struct source)); 1695 if (stack == NULL) 1696 err(1, "recursion too deep"); 1697 bmachine.readstack_sz = newsz; 1698 bmachine.readstack = stack; 1699 } 1700 src_setstring(&bmachine.readstack[++bmachine.readsp], p); 1701 } 1702 1703 static void 1704 eval_line(void) 1705 { 1706 /* Always read from stdin */ 1707 struct source in; 1708 char *p; 1709 1710 clearerr(stdin); 1711 src_setstream(&in, stdin); 1712 p = (*in.vtable->readline)(&in); 1713 eval_string(p); 1714 } 1715 1716 static void 1717 eval_tos(void) 1718 { 1719 char *p; 1720 1721 p = pop_string(); 1722 if (p == NULL) 1723 return; 1724 eval_string(p); 1725 } 1726 1727 void 1728 eval(void) 1729 { 1730 int ch; 1731 1732 for (;;) { 1733 ch = readch(); 1734 if (ch == EOF) { 1735 if (bmachine.readsp == 0) 1736 return; 1737 src_free(); 1738 bmachine.readsp--; 1739 continue; 1740 } 1741 if (bmachine.interrupted) { 1742 if (bmachine.readsp > 0) { 1743 src_free(); 1744 bmachine.readsp--; 1745 continue; 1746 } else 1747 bmachine.interrupted = false; 1748 } 1749 #ifdef DEBUGGING 1750 (void)fprintf(stderr, "# %c\n", ch); 1751 stack_print(stderr, &bmachine.stack, "* ", 1752 bmachine.obase); 1753 (void)fprintf(stderr, "%zd =>\n", bmachine.readsp); 1754 #endif 1755 1756 if (0 <= ch && ch < UCHAR_MAX) 1757 (*jump_table[ch])(); 1758 else 1759 warnx("internal error: opcode %d", ch); 1760 1761 #ifdef DEBUGGING 1762 stack_print(stderr, &bmachine.stack, "* ", 1763 bmachine.obase); 1764 (void)fprintf(stderr, "%zd ==\n", bmachine.readsp); 1765 #endif 1766 } 1767 } 1768