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