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