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