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