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