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