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