GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/bc/../dc/bcode.c Lines: 442 758 58.3 %
Date: 2017-11-13 Branches: 147 329 44.7 %

Line Branch Exec Source
1
/*	$OpenBSD: bcode.c,v 1.51 2017/02/26 11:29:55 otto Exp $	*/
2
3
/*
4
 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <err.h>
20
#include <limits.h>
21
#include <signal.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
26
#include "extern.h"
27
28
/* #define	DEBUGGING */
29
30
#define MAX_ARRAY_INDEX		2048
31
#define READSTACK_SIZE		8
32
33
#define NO_ELSE			-2	/* -1 is EOF */
34
#define REG_ARRAY_SIZE_SMALL	(UCHAR_MAX + 1)
35
#define REG_ARRAY_SIZE_BIG	(UCHAR_MAX + 1 + USHRT_MAX + 1)
36
37
struct bmachine {
38
	struct stack		stack;
39
	u_int			scale;
40
	u_int			obase;
41
	u_int			ibase;
42
	size_t			readsp;
43
	bool			extended_regs;
44
	size_t			reg_array_size;
45
	struct stack		*reg;
46
	volatile sig_atomic_t	interrupted;
47
	struct source		*readstack;
48
	size_t			readstack_sz;
49
};
50
51
static struct bmachine	bmachine;
52
static void sighandler(int);
53
54
static __inline int	readch(void);
55
static __inline void	unreadch(void);
56
static __inline char	*readline(void);
57
static __inline void	src_free(void);
58
59
static __inline u_int	max(u_int, u_int);
60
static u_long		get_ulong(struct number *);
61
62
static __inline void	push_number(struct number *);
63
static __inline void	push_string(char *);
64
static __inline void	push(struct value *);
65
static __inline struct value *tos(void);
66
static __inline struct number	*pop_number(void);
67
static __inline char	*pop_string(void);
68
static __inline void	clear_stack(void);
69
static __inline void	print_tos(void);
70
static void		print_err(void);
71
static void		pop_print(void);
72
static void		pop_printn(void);
73
static __inline void	print_stack(void);
74
static __inline void	dup(void);
75
static void		swap(void);
76
static void		drop(void);
77
78
static void		get_scale(void);
79
static void		set_scale(void);
80
static void		get_obase(void);
81
static void		set_obase(void);
82
static void		get_ibase(void);
83
static void		set_ibase(void);
84
static void		stackdepth(void);
85
static void		push_scale(void);
86
static u_int		count_digits(const struct number *);
87
static void		num_digits(void);
88
static void		to_ascii(void);
89
static void		push_line(void);
90
static void		comment(void);
91
static void		badd(void);
92
static void		bsub(void);
93
static void		bmul(void);
94
static void		bdiv(void);
95
static void		bmod(void);
96
static void		bdivmod(void);
97
static void		bexp(void);
98
static bool		bsqrt_stop(const BIGNUM *, const BIGNUM *, u_int *);
99
static void		bsqrt(void);
100
static void		not(void);
101
static void		equal_numbers(void);
102
static void		less_numbers(void);
103
static void		lesseq_numbers(void);
104
static void		equal(void);
105
static void		not_equal(void);
106
static void		less(void);
107
static void		not_less(void);
108
static void		greater(void);
109
static void		not_greater(void);
110
static void		not_compare(void);
111
static bool		compare_numbers(enum bcode_compare, struct number *,
112
			    struct number *);
113
static void		compare(enum bcode_compare);
114
static int		readreg(void);
115
static void		load(void);
116
static void		store(void);
117
static void		load_stack(void);
118
static void		store_stack(void);
119
static void		load_array(void);
120
static void		store_array(void);
121
static void		nop(void);
122
static void		quit(void);
123
static void		quitN(void);
124
static void		skipN(void);
125
static void		skip_until_mark(void);
126
static void		parse_number(void);
127
static void		unknown(void);
128
static void		eval_string(char *);
129
static void		eval_line(void);
130
static void		eval_tos(void);
131
132
133
typedef void		(*opcode_function)(void);
134
135
struct jump_entry {
136
	u_char		ch;
137
	opcode_function	f;
138
};
139
140
static opcode_function jump_table[UCHAR_MAX];
141
142
static const struct jump_entry jump_table_data[] = {
143
	{ ' ',	nop		},
144
	{ '!',	not_compare	},
145
	{ '#',	comment		},
146
	{ '%',	bmod		},
147
	{ '(',	less_numbers	},
148
	{ '*',	bmul		},
149
	{ '+',	badd		},
150
	{ '-',	bsub		},
151
	{ '.',	parse_number	},
152
	{ '/',	bdiv		},
153
	{ '0',	parse_number	},
154
	{ '1',	parse_number	},
155
	{ '2',	parse_number	},
156
	{ '3',	parse_number	},
157
	{ '4',	parse_number	},
158
	{ '5',	parse_number	},
159
	{ '6',	parse_number	},
160
	{ '7',	parse_number	},
161
	{ '8',	parse_number	},
162
	{ '9',	parse_number	},
163
	{ ':',	store_array	},
164
	{ ';',	load_array	},
165
	{ '<',	less		},
166
	{ '=',	equal		},
167
	{ '>',	greater		},
168
	{ '?',	eval_line	},
169
	{ 'A',	parse_number	},
170
	{ 'B',	parse_number	},
171
	{ 'C',	parse_number	},
172
	{ 'D',	parse_number	},
173
	{ 'E',	parse_number	},
174
	{ 'F',	parse_number	},
175
	{ 'G',	equal_numbers	},
176
	{ 'I',	get_ibase	},
177
	{ 'J',	skipN		},
178
	{ 'K',	get_scale	},
179
	{ 'L',	load_stack	},
180
	{ 'M',	nop		},
181
	{ 'N',	not		},
182
	{ 'O',	get_obase	},
183
	{ 'P',	pop_print	},
184
	{ 'Q',	quitN		},
185
	{ 'R',	drop		},
186
	{ 'S',	store_stack	},
187
	{ 'X',	push_scale	},
188
	{ 'Z',	num_digits	},
189
	{ '[',	push_line	},
190
	{ '\f',	nop		},
191
	{ '\n',	nop		},
192
	{ '\r',	nop		},
193
	{ '\t',	nop		},
194
	{ '^',	bexp		},
195
	{ '_',	parse_number	},
196
	{ 'a',	to_ascii	},
197
	{ 'c',	clear_stack	},
198
	{ 'd',	dup		},
199
	{ 'e',	print_err	},
200
	{ 'f',	print_stack	},
201
	{ 'i',	set_ibase	},
202
	{ 'k',	set_scale	},
203
	{ 'l',	load		},
204
	{ 'n',	pop_printn	},
205
	{ 'o',	set_obase	},
206
	{ 'p',	print_tos	},
207
	{ 'q',	quit		},
208
	{ 'r',	swap		},
209
	{ 's',	store		},
210
	{ 'v',	bsqrt		},
211
	{ 'x',	eval_tos	},
212
	{ 'z',	stackdepth	},
213
	{ '{',	lesseq_numbers	},
214
	{ '~',	bdivmod		}
215
};
216
217
#define JUMP_TABLE_DATA_SIZE \
218
	(sizeof(jump_table_data)/sizeof(jump_table_data[0]))
219
220
/* ARGSUSED */
221
static void
222
sighandler(int ignored)
223
{
224
	bmachine.interrupted = true;
225
}
226
227
void
228
init_bmachine(bool extended_registers)
229
{
230
	int i;
231
232
2076
	bmachine.extended_regs = extended_registers;
233
2076
	bmachine.reg_array_size = bmachine.extended_regs ?
234
	    REG_ARRAY_SIZE_BIG : REG_ARRAY_SIZE_SMALL;
235
236
2076
	bmachine.reg = calloc(bmachine.reg_array_size,
237
	    sizeof(bmachine.reg[0]));
238
2076
	if (bmachine.reg == NULL)
239
		err(1, NULL);
240
241
1062912
	for (i = 0; i < UCHAR_MAX; i++)
242
529380
		jump_table[i] = unknown;
243
303096
	for (i = 0; i < JUMP_TABLE_DATA_SIZE; i++)
244
149472
		jump_table[jump_table_data[i].ch] = jump_table_data[i].f;
245
246
2076
	stack_init(&bmachine.stack);
247
248
273172536
	for (i = 0; i < bmachine.reg_array_size; i++)
249
136584192
		stack_init(&bmachine.reg[i]);
250
251
2076
	bmachine.readstack_sz = READSTACK_SIZE;
252
2076
	bmachine.readstack = calloc(sizeof(struct source),
253
	    bmachine.readstack_sz);
254
2076
	if (bmachine.readstack == NULL)
255
		err(1, NULL);
256
2076
	bmachine.obase = bmachine.ibase = 10;
257
2076
	(void)signal(SIGINT, sighandler);
258
2076
}
259
260
u_int
261
bmachine_scale(void)
262
{
263
42768
	return bmachine.scale;
264
}
265
266
/* Reset the things needed before processing a (new) file */
267
void
268
reset_bmachine(struct source *src)
269
{
270
4152
	bmachine.readsp = 0;
271
2076
	bmachine.readstack[0] = *src;
272
2076
}
273
274
static __inline int
275
readch(void)
276
{
277
4471176
	struct source *src = &bmachine.readstack[bmachine.readsp];
278
279
2235588
	return src->vtable->readchar(src);
280
}
281
282
static __inline void
283
unreadch(void)
284
{
285
445384
	struct source *src = &bmachine.readstack[bmachine.readsp];
286
287
222692
	src->vtable->unreadchar(src);
288
222692
}
289
290
static __inline char *
291
readline(void)
292
{
293
	struct source *src = &bmachine.readstack[bmachine.readsp];
294
295
	return src->vtable->readline(src);
296
}
297
298
static __inline void
299
src_free(void)
300
{
301
61864
	struct source *src = &bmachine.readstack[bmachine.readsp];
302
303
30932
	src->vtable->free(src);
304
30932
}
305
306
#ifdef DEBUGGING
307
void
308
pn(const char *str, const struct number *n)
309
{
310
	char *p = BN_bn2dec(n->number);
311
	if (p == NULL)
312
		err(1, "BN_bn2dec failed");
313
	(void)fputs(str, stderr);
314
	(void)fprintf(stderr, " %s (%u)\n" , p, n->scale);
315
	OPENSSL_free(p);
316
}
317
318
void
319
pbn(const char *str, const BIGNUM *n)
320
{
321
	char *p = BN_bn2dec(n);
322
	if (p == NULL)
323
		err(1, "BN_bn2dec failed");
324
	(void)fputs(str, stderr);
325
	(void)fprintf(stderr, " %s\n", p);
326
	OPENSSL_free(p);
327
}
328
329
#endif
330
331
static __inline u_int
332
max(u_int a, u_int b)
333
{
334
362496
	return a > b ? a : b;
335
}
336
337
static unsigned long factors[] = {
338
	0, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
339
	100000000, 1000000000
340
};
341
342
void
343
scale_number(BIGNUM *n, int s)
344
{
345
	int abs_scale;
346
347
295848
	if (s == 0)
348
29444
		return;
349
350
118480
	abs_scale = s > 0 ? s : -s;
351
352
118480
	if (abs_scale < sizeof(factors)/sizeof(factors[0])) {
353
19452
		if (s > 0)
354
17216
			bn_check(BN_mul_word(n, factors[abs_scale]));
355
		else
356
2236
			(void)BN_div_word(n, factors[abs_scale]);
357
	} else {
358
		BIGNUM *a, *p;
359
		BN_CTX *ctx;
360
361
99028
		a = BN_new();
362
99028
		bn_checkp(a);
363
99028
		p = BN_new();
364
99028
		bn_checkp(p);
365
99028
		ctx = BN_CTX_new();
366
99028
		bn_checkp(ctx);
367
368
99028
		bn_check(BN_set_word(a, 10));
369
99028
		bn_check(BN_set_word(p, abs_scale));
370
99028
		bn_check(BN_exp(a, a, p, ctx));
371
99028
		if (s > 0)
372
80140
			bn_check(BN_mul(n, n, a, ctx));
373
		else
374
18888
			bn_check(BN_div(n, NULL, n, a, ctx));
375
99028
		BN_CTX_free(ctx);
376
99028
		BN_free(a);
377
99028
		BN_free(p);
378
	}
379
266404
}
380
381
void
382
split_number(const struct number *n, BIGNUM *i, BIGNUM *f)
383
{
384
	u_long rem;
385
386
53120
	bn_checkp(BN_copy(i, n->number));
387
388
26560
	if (n->scale == 0 && f != NULL)
389
1432
		bn_check(BN_set_word(f, 0));
390
25128
	else if (n->scale < sizeof(factors)/sizeof(factors[0])) {
391
3556
		rem = BN_div_word(i, factors[n->scale]);
392
3556
		if (f != NULL)
393
1972
			bn_check(BN_set_word(f, rem));
394
	} else {
395
		BIGNUM *a, *p;
396
		BN_CTX *ctx;
397
398
21572
		a = BN_new();
399
21572
		bn_checkp(a);
400
21572
		p = BN_new();
401
21572
		bn_checkp(p);
402
21572
		ctx = BN_CTX_new();
403
21572
		bn_checkp(ctx);
404
405
21572
		bn_check(BN_set_word(a, 10));
406
21572
		bn_check(BN_set_word(p, n->scale));
407
21572
		bn_check(BN_exp(a, a, p, ctx));
408
21572
		bn_check(BN_div(i, f, n->number, a, ctx));
409
21572
		BN_CTX_free(ctx);
410
21572
		BN_free(a);
411
21572
		BN_free(p);
412
	}
413
26560
}
414
415
void
416
normalize(struct number *n, u_int s)
417
{
418
292152
	scale_number(n->number, s - n->scale);
419
146076
	n->scale = s;
420
146076
}
421
422
static u_long
423
get_ulong(struct number *n)
424
{
425
46568
	normalize(n, 0);
426
23284
	return BN_get_word(n->number);
427
}
428
429
void
430
negate(struct number *n)
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
669928
	stack_pushnumber(&bmachine.stack, n);
439
334964
}
440
441
static __inline void
442
push_string(char *string)
443
{
444
165760
	stack_pushstring(&bmachine.stack, string);
445
82880
}
446
447
static __inline void
448
push(struct value *v)
449
{
450
664832
	stack_push(&bmachine.stack, v);
451
332416
}
452
453
static __inline struct value *
454
tos(void)
455
{
456
4152
	return stack_tos(&bmachine.stack);
457
}
458
459
static __inline struct value *
460
pop(void)
461
{
462
641000
	return stack_pop(&bmachine.stack);
463
}
464
465
static __inline struct number *
466
pop_number(void)
467
{
468
891800
	return stack_popnumber(&bmachine.stack);
469
}
470
471
static __inline char *
472
pop_string(void)
473
{
474
7504
	return stack_popstring(&bmachine.stack);
475
}
476
477
static __inline void
478
clear_stack(void)
479
{
480
	stack_clear(&bmachine.stack);
481
}
482
483
static __inline void
484
print_stack(void)
485
{
486
	stack_print(stdout, &bmachine.stack, "", bmachine.obase);
487
}
488
489
static __inline void
490
print_tos(void)
491
{
492
4152
	struct value *value = tos();
493
2076
	if (value != NULL) {
494
2076
		print_value(stdout, value, "", bmachine.obase);
495
4152
		(void)putchar('\n');
496
	}
497
	else
498
		warnx("stack empty");
499
2076
}
500
501
static void
502
print_err(void)
503
{
504
	struct value *value = tos();
505
	if (value != NULL) {
506
		print_value(stderr, value, "", bmachine.obase);
507
		(void)putc('\n', stderr);
508
	}
509
	else
510
		warnx("stack empty");
511
}
512
513
static void
514
pop_print(void)
515
{
516
	struct value *value = pop();
517
518
	if (value != NULL) {
519
		switch (value->type) {
520
		case BCODE_NONE:
521
			break;
522
		case BCODE_NUMBER:
523
			normalize(value->u.num, 0);
524
			print_ascii(stdout, value->u.num);
525
			(void)fflush(stdout);
526
			break;
527
		case BCODE_STRING:
528
			(void)fputs(value->u.string, stdout);
529
			(void)fflush(stdout);
530
			break;
531
		}
532
		stack_free_value(value);
533
	}
534
}
535
536
static void
537
pop_printn(void)
538
{
539
	struct value *value = pop();
540
541
	if (value != NULL) {
542
		print_value(stdout, value, "", bmachine.obase);
543
		(void)fflush(stdout);
544
		stack_free_value(value);
545
	}
546
}
547
548
static __inline void
549
dup(void)
550
{
551
39784
	stack_dup(&bmachine.stack);
552
19892
}
553
554
static void
555
swap(void)
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
11312
	n = new_number();
574
5656
	bn_check(BN_set_word(n->number, bmachine.scale));
575
5656
	push_number(n);
576
5656
}
577
578
static void
579
set_scale(void)
580
{
581
	struct number	*n;
582
	u_long		scale;
583
584
24168
	n = pop_number();
585
12084
	if (n != NULL) {
586
12084
		if (BN_is_negative(n->number))
587
			warnx("scale must be a nonnegative number");
588
		else {
589
12084
			scale = get_ulong(n);
590
12084
			if (scale != BN_MASK2 && scale <= UINT_MAX)
591
12084
				bmachine.scale = (u_int)scale;
592
			else
593
				warnx("scale too large");
594
			}
595
12084
		free_number(n);
596
12084
	}
597
12084
}
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
7448
	n = new_number();
632
3724
	bn_check(BN_set_word(n->number, bmachine.ibase));
633
3724
	push_number(n);
634
3724
}
635
636
static void
637
set_ibase(void)
638
{
639
	struct number	*n;
640
	u_long		base;
641
642
14896
	n = pop_number();
643
7448
	if (n != NULL) {
644
7448
		base = get_ulong(n);
645
7448
		if (base != BN_MASK2 && 2 <= base && base <= 16)
646
7448
			bmachine.ibase = (u_int)base;
647
		else
648
			warnx("input base must be a number between 2 and 16 "
649
			    "(inclusive)");
650
7448
		free_number(n);
651
7448
	}
652
7448
}
653
654
static void
655
stackdepth(void)
656
{
657
	size_t i;
658
	struct number *n;
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 value	*value;
670
	u_int		scale = 0;
671
	struct number	*n;
672
673
674
4144
	value = pop();
675
2072
	if (value != NULL) {
676
4144
		switch (value->type) {
677
		case BCODE_NONE:
678
			return;
679
		case BCODE_NUMBER:
680
2072
			scale = value->u.num->scale;
681
2072
			break;
682
		case BCODE_STRING:
683
			break;
684
		}
685
2072
		stack_free_value(value);
686
2072
		n = new_number();
687
2072
		bn_check(BN_set_word(n->number, scale));
688
2072
		push_number(n);
689
2072
	}
690
4144
}
691
692
static u_int
693
count_digits(const struct number *n)
694
{
695
	struct number	*int_part, *fract_part;
696
	u_int		i;
697
698
6272
	if (BN_is_zero(n->number))
699
108
		return n->scale ? n->scale : 1;
700
701
3100
	int_part = new_number();
702
3100
	fract_part = new_number();
703
3100
	fract_part->scale = n->scale;
704
3100
	split_number(n, int_part->number, fract_part->number);
705
706
	i = 0;
707
14192
	while (!BN_is_zero(int_part->number)) {
708
3996
		(void)BN_div_word(int_part->number, 10);
709
3996
		i++;
710
	}
711
3100
	free_number(int_part);
712
3100
	free_number(fract_part);
713
3100
	return i + n->scale;
714
3136
}
715
716
static void
717
num_digits(void)
718
{
719
	struct value	*value;
720
	size_t		digits;
721
	struct number	*n = NULL;
722
723
6272
	value = pop();
724
3136
	if (value != NULL) {
725

6272
		switch (value->type) {
726
		case BCODE_NONE:
727
			return;
728
		case BCODE_NUMBER:
729
3136
			digits = count_digits(value->u.num);
730
3136
			n = new_number();
731
3136
			bn_check(BN_set_word(n->number, digits));
732
3136
			break;
733
		case BCODE_STRING:
734
			digits = strlen(value->u.string);
735
			n = new_number();
736
			bn_check(BN_set_word(n->number, digits));
737
			break;
738
		}
739
3136
		stack_free_value(value);
740
3136
		push_number(n);
741
3136
	}
742
6272
}
743
744
static void
745
to_ascii(void)
746
{
747
	char		str[2];
748
	struct value	*value;
749
	struct number	*n;
750
751
	value = pop();
752
	if (value != NULL) {
753
		str[1] = '\0';
754
		switch (value->type) {
755
		case BCODE_NONE:
756
			return;
757
		case BCODE_NUMBER:
758
			n = value->u.num;
759
			normalize(n, 0);
760
			if (BN_num_bits(n->number) > 8)
761
				bn_check(BN_mask_bits(n->number, 8));
762
			str[0] = (char)BN_get_word(n->number);
763
			break;
764
		case BCODE_STRING:
765
			str[0] = value->u.string[0];
766
			break;
767
		}
768
		stack_free_value(value);
769
		push_string(bstrdup(str));
770
	}
771
}
772
773
static int
774
readreg(void)
775
{
776
	int idx, ch1, ch2;
777
778
1399008
	idx = readch();
779

699504
	if (idx == 0xff && bmachine.extended_regs) {
780
		ch1 = readch();
781
		ch2 = readch();
782
		if (ch1 == EOF || ch2 == EOF) {
783
			warnx("unexpected eof");
784
			idx = -1;
785
		} else
786
			idx = (ch1 << 8) + ch2 + UCHAR_MAX + 1;
787
	}
788

1399008
	if (idx < 0 || idx >= bmachine.reg_array_size) {
789
		warnx("internal error: reg num = %d", idx);
790
		idx = -1;
791
	}
792
699504
	return idx;
793
}
794
795
static void
796
load(void)
797
{
798
	int		idx;
799
588224
	struct value	*v, copy;
800
	struct number	*n;
801
802
294112
	idx = readreg();
803
294112
	if (idx >= 0) {
804
294112
		v = stack_tos(&bmachine.reg[idx]);
805
294112
		if (v == NULL) {
806
			n = new_number();
807
			bn_check(BN_set_word(n->number, 0));
808
			push_number(n);
809
		} else
810
294112
			push(stack_dup_value(v, &copy));
811
	}
812
294112
}
813
814
static void
815
store(void)
816
{
817
	int		idx;
818
	struct value	*val;
819
820
553976
	idx = readreg();
821
276988
	if (idx >= 0) {
822
276988
		val = pop();
823
276988
		if (val == NULL) {
824
			return;
825
		}
826
276988
		stack_set_tos(&bmachine.reg[idx], val);
827
276988
	}
828
553976
}
829
830
static void
831
load_stack(void)
832
{
833
	int		idx;
834
	struct stack	*stack;
835
	struct value	*value;
836
837
76608
	idx = readreg();
838
38304
	if (idx >= 0) {
839
38304
		stack = &bmachine.reg[idx];
840
		value = NULL;
841
38304
		if (stack_size(stack) > 0) {
842
38304
			value = stack_pop(stack);
843
38304
		}
844
38304
		if (value != NULL)
845
38304
			push(value);
846
		else
847
			warnx("stack register '%c' (0%o) is empty",
848
			    idx, idx);
849
	}
850
38304
}
851
852
static void
853
store_stack(void)
854
{
855
	int		idx;
856
	struct value	*value;
857
858
76608
	idx = readreg();
859
38304
	if (idx >= 0) {
860
38304
		value = pop();
861
38304
		if (value == NULL)
862
			return;
863
38304
		stack_push(&bmachine.reg[idx], value);
864
38304
	}
865
76608
}
866
867
static void
868
load_array(void)
869
{
870
	int			reg;
871
	struct number		*inumber, *n;
872
	u_long			idx;
873
	struct stack		*stack;
874
	struct value		*v, copy;
875
876
	reg = readreg();
877
	if (reg >= 0) {
878
		inumber = pop_number();
879
		if (inumber == NULL)
880
			return;
881
		idx = get_ulong(inumber);
882
		if (BN_is_negative(inumber->number))
883
			warnx("negative idx");
884
		else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX)
885
			warnx("idx too big");
886
		else {
887
			stack = &bmachine.reg[reg];
888
			v = frame_retrieve(stack, idx);
889
			if (v == NULL || v->type == BCODE_NONE) {
890
				n = new_number();
891
				bn_check(BN_set_word(n->number, 0));
892
				push_number(n);
893
			}
894
			else
895
				push(stack_dup_value(v, &copy));
896
		}
897
		free_number(inumber);
898
	}
899
}
900
901
static void
902
store_array(void)
903
{
904
	int			reg;
905
	struct number		*inumber;
906
	u_long			idx;
907
	struct value		*value;
908
	struct stack		*stack;
909
910
	reg = readreg();
911
	if (reg >= 0) {
912
		inumber = pop_number();
913
		if (inumber == NULL)
914
			return;
915
		value = pop();
916
		if (value == NULL) {
917
			free_number(inumber);
918
			return;
919
		}
920
		idx = get_ulong(inumber);
921
		if (BN_is_negative(inumber->number)) {
922
			warnx("negative idx");
923
			stack_free_value(value);
924
		} else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) {
925
			warnx("idx too big");
926
			stack_free_value(value);
927
		} else {
928
			stack = &bmachine.reg[reg];
929
			frame_assign(stack, idx, value);
930
		}
931
		free_number(inumber);
932
	}
933
}
934
935
static void
936
push_line(void)
937
{
938
165760
	push_string(read_string(&bmachine.readstack[bmachine.readsp]));
939
82880
}
940
941
static void
942
comment(void)
943
{
944
	free(readline());
945
}
946
947
static void
948
badd(void)
949
{
950
	struct number	*a, *b;
951
	struct number	*r;
952
953
87128
	a = pop_number();
954
43564
	if (a == NULL)
955
		return;
956
43564
	b = pop_number();
957
43564
	if (b == NULL) {
958
		push_number(a);
959
		return;
960
	}
961
962
43564
	r = new_number();
963
43564
	r->scale = max(a->scale, b->scale);
964
43564
	if (r->scale > a->scale)
965
2680
		normalize(a, r->scale);
966
40884
	else if (r->scale > b->scale)
967
1824
		normalize(b, r->scale);
968
43564
	bn_check(BN_add(r->number, a->number, b->number));
969
43564
	push_number(r);
970
43564
	free_number(a);
971
43564
	free_number(b);
972
87128
}
973
974
static void
975
bsub(void)
976
{
977
	struct number	*a, *b;
978
	struct number	*r;
979
980
27784
	a = pop_number();
981
13892
	if (a == NULL)
982
		return;
983
13892
	b = pop_number();
984
13892
	if (b == NULL) {
985
		push_number(a);
986
		return;
987
	}
988
989
13892
	r = new_number();
990
991
13892
	r->scale = max(a->scale, b->scale);
992
13892
	if (r->scale > a->scale)
993
796
		normalize(a, r->scale);
994
13096
	else if (r->scale > b->scale)
995
4612
		normalize(b, r->scale);
996
13892
	bn_check(BN_sub(r->number, b->number, a->number));
997
13892
	push_number(r);
998
13892
	free_number(a);
999
13892
	free_number(b);
1000
27784
}
1001
1002
void
1003
bmul_number(struct number *r, struct number *a, struct number *b, u_int scale)
1004
{
1005
	BN_CTX		*ctx;
1006
1007
	/* Create copies of the scales, since r might be equal to a or b */
1008
191136
	u_int ascale = a->scale;
1009
95568
	u_int bscale = b->scale;
1010
95568
	u_int rscale = ascale + bscale;
1011
1012
95568
	ctx = BN_CTX_new();
1013
95568
	bn_checkp(ctx);
1014
95568
	bn_check(BN_mul(r->number, a->number, b->number, ctx));
1015
95568
	BN_CTX_free(ctx);
1016
1017
95568
	r->scale = rscale;
1018

154896
	if (rscale > bmachine.scale && rscale > ascale && rscale > bscale)
1019
21124
		normalize(r, max(scale, max(ascale, bscale)));
1020
95568
}
1021
1022
static void
1023
bmul(void)
1024
{
1025
	struct number	*a, *b;
1026
	struct number	*r;
1027
1028
146968
	a = pop_number();
1029
73484
	if (a == NULL)
1030
		return;
1031
73484
	b = pop_number();
1032
73484
	if (b == NULL) {
1033
		push_number(a);
1034
		return;
1035
	}
1036
1037
73484
	r = new_number();
1038
73484
	bmul_number(r, a, b, bmachine.scale);
1039
1040
73484
	push_number(r);
1041
73484
	free_number(a);
1042
73484
	free_number(b);
1043
146968
}
1044
1045
static void
1046
bdiv(void)
1047
{
1048
	struct number	*a, *b;
1049
	struct number	*r;
1050
	u_int		scale;
1051
	BN_CTX		*ctx;
1052
1053
54792
	a = pop_number();
1054
27396
	if (a == NULL)
1055
		return;
1056
27396
	b = pop_number();
1057
27396
	if (b == NULL) {
1058
		push_number(a);
1059
		return;
1060
	}
1061
1062
27396
	r = new_number();
1063
27396
	r->scale = bmachine.scale;
1064
27396
	scale = max(a->scale, b->scale);
1065
1066
27396
	if (BN_is_zero(a->number))
1067
		warnx("divide by zero");
1068
	else {
1069
27396
		normalize(a, scale);
1070
27396
		normalize(b, scale + r->scale);
1071
1072
27396
		ctx = BN_CTX_new();
1073
27396
		bn_checkp(ctx);
1074
27396
		bn_check(BN_div(r->number, NULL, b->number, a->number, ctx));
1075
27396
		BN_CTX_free(ctx);
1076
	}
1077
27396
	push_number(r);
1078
27396
	free_number(a);
1079
27396
	free_number(b);
1080
54792
}
1081
1082
static void
1083
bmod(void)
1084
{
1085
	struct number	*a, *b;
1086
	struct number	*r;
1087
	u_int		scale;
1088
	BN_CTX		*ctx;
1089
1090
1680
	a = pop_number();
1091
840
	if (a == NULL)
1092
		return;
1093
840
	b = pop_number();
1094
840
	if (b == NULL) {
1095
		push_number(a);
1096
		return;
1097
	}
1098
1099
840
	r = new_number();
1100
840
	scale = max(a->scale, b->scale);
1101
840
	r->scale = max(b->scale, a->scale + bmachine.scale);
1102
1103
840
	if (BN_is_zero(a->number))
1104
		warnx("remainder by zero");
1105
	else {
1106
840
		normalize(a, scale);
1107
840
		normalize(b, scale + bmachine.scale);
1108
1109
840
		ctx = BN_CTX_new();
1110
840
		bn_checkp(ctx);
1111
840
		bn_check(BN_mod(r->number, b->number, a->number, ctx));
1112
840
		BN_CTX_free(ctx);
1113
	}
1114
840
	push_number(r);
1115
840
	free_number(a);
1116
840
	free_number(b);
1117
1680
}
1118
1119
static void
1120
bdivmod(void)
1121
{
1122
	struct number	*a, *b;
1123
	struct number	*rdiv, *rmod;
1124
	u_int		scale;
1125
	BN_CTX		*ctx;
1126
1127
	a = pop_number();
1128
	if (a == NULL)
1129
		return;
1130
	b = pop_number();
1131
	if (b == NULL) {
1132
		push_number(a);
1133
		return;
1134
	}
1135
1136
	rdiv = new_number();
1137
	rmod = new_number();
1138
	rdiv->scale = bmachine.scale;
1139
	rmod->scale = max(b->scale, a->scale + bmachine.scale);
1140
	scale = max(a->scale, b->scale);
1141
1142
	if (BN_is_zero(a->number))
1143
		warnx("divide by zero");
1144
	else {
1145
		normalize(a, scale);
1146
		normalize(b, scale + bmachine.scale);
1147
1148
		ctx = BN_CTX_new();
1149
		bn_checkp(ctx);
1150
		bn_check(BN_div(rdiv->number, rmod->number,
1151
		    b->number, a->number, ctx));
1152
		BN_CTX_free(ctx);
1153
	}
1154
	push_number(rdiv);
1155
	push_number(rmod);
1156
	free_number(a);
1157
	free_number(b);
1158
}
1159
1160
static void
1161
bexp(void)
1162
{
1163
	struct number	*a, *p;
1164
	struct number	*r;
1165
	bool		neg;
1166
	u_int		rscale;
1167
1168
392
	p = pop_number();
1169
196
	if (p == NULL)
1170
		return;
1171
196
	a = pop_number();
1172
196
	if (a == NULL) {
1173
		push_number(p);
1174
		return;
1175
	}
1176
1177
196
	if (p->scale != 0) {
1178
		BIGNUM *i, *f;
1179
		i = BN_new();
1180
		bn_checkp(i);
1181
		f = BN_new();
1182
		bn_checkp(f);
1183
		split_number(p, i, f);
1184
		if (!BN_is_zero(f))
1185
			warnx("Runtime warning: non-zero fractional part in exponent");
1186
		BN_free(i);
1187
		BN_free(f);
1188
	}
1189
1190
196
	normalize(p, 0);
1191
1192
	neg = false;
1193
196
	if (BN_is_negative(p->number)) {
1194
		neg = true;
1195
		negate(p);
1196
		rscale = bmachine.scale;
1197
	} else {
1198
		/* Posix bc says min(a.scale * b, max(a.scale, scale) */
1199
		u_long	b;
1200
		u_int	m;
1201
1202
196
		b = BN_get_word(p->number);
1203
196
		m = max(a->scale, bmachine.scale);
1204
196
		rscale = a->scale * (u_int)b;
1205

392
		if (rscale > m || (a->scale > 0 && (b == BN_MASK2 ||
1206
		    b > UINT_MAX)))
1207
			rscale = m;
1208
	}
1209
1210
196
	if (BN_is_zero(p->number)) {
1211
		r = new_number();
1212
		bn_check(BN_one(r->number));
1213
		normalize(r, rscale);
1214
	} else {
1215
		u_int ascale, mscale;
1216
1217
196
		ascale = a->scale;
1218
672
		while (!BN_is_bit_set(p->number, 0)) {
1219
140
			ascale *= 2;
1220
140
			bmul_number(a, a, a, ascale);
1221
140
			bn_check(BN_rshift1(p->number, p->number));
1222
		}
1223
1224
196
		r = dup_number(a);
1225
196
		bn_check(BN_rshift1(p->number, p->number));
1226
1227
		mscale = ascale;
1228
1008
		while (!BN_is_zero(p->number)) {
1229
308
			ascale *= 2;
1230
308
			bmul_number(a, a, a, ascale);
1231
308
			if (BN_is_bit_set(p->number, 0)) {
1232
252
				mscale += ascale;
1233
252
				bmul_number(r, r, a, mscale);
1234
252
			}
1235
308
			bn_check(BN_rshift1(p->number, p->number));
1236
		}
1237
1238
196
		if (neg) {
1239
			BN_CTX	*ctx;
1240
			BIGNUM	*one;
1241
1242
			one = BN_new();
1243
			bn_checkp(one);
1244
			bn_check(BN_one(one));
1245
			ctx = BN_CTX_new();
1246
			bn_checkp(ctx);
1247
			scale_number(one, r->scale + rscale);
1248
1249
			if (BN_is_zero(r->number))
1250
				warnx("divide by zero");
1251
			else
1252
				bn_check(BN_div(r->number, NULL, one,
1253
				    r->number, ctx));
1254
			BN_free(one);
1255
			BN_CTX_free(ctx);
1256
			r->scale = rscale;
1257
		} else
1258
196
			normalize(r, rscale);
1259
	}
1260
196
	push_number(r);
1261
196
	free_number(a);
1262
196
	free_number(p);
1263
392
}
1264
1265
static bool
1266
bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount)
1267
{
1268
	BIGNUM *r;
1269
	bool ret;
1270
1271
7592
	r = BN_new();
1272
3796
	bn_checkp(r);
1273
3796
	bn_check(BN_sub(r, x, y));
1274

6260
	if (BN_is_one(r))
1275
		(*onecount)++;
1276
3796
	ret = BN_is_zero(r);
1277
3796
	BN_free(r);
1278
10716
	return ret || *onecount > 1;
1279
}
1280
1281
static void
1282
bsqrt(void)
1283
{
1284
	struct number	*n;
1285
	struct number	*r;
1286
	BIGNUM		*x, *y;
1287
1344
	u_int		scale, onecount;
1288
	BN_CTX		*ctx;
1289
1290
672
	onecount = 0;
1291
672
	n = pop_number();
1292
672
	if (n == NULL)
1293
		return;
1294
672
	if (BN_is_zero(n->number)) {
1295
		r = new_number();
1296
		push_number(r);
1297
672
	} else if (BN_is_negative(n->number))
1298
		warnx("square root of negative number");
1299
	else {
1300
672
		scale = max(bmachine.scale, n->scale);
1301
672
		normalize(n, 2*scale);
1302
672
		x = BN_dup(n->number);
1303
672
		bn_checkp(x);
1304
672
		bn_check(BN_rshift(x, x, BN_num_bits(x)/2));
1305
672
		y = BN_new();
1306
672
		bn_checkp(y);
1307
672
		ctx = BN_CTX_new();
1308
672
		bn_checkp(ctx);
1309
3796
		for (;;) {
1310
3796
			bn_checkp(BN_copy(y, x));
1311
3796
			bn_check(BN_div(x, NULL, n->number, x, ctx));
1312
3796
			bn_check(BN_add(x, x, y));
1313
3796
			bn_check(BN_rshift1(x, x));
1314
3796
			if (bsqrt_stop(x, y, &onecount))
1315
				break;
1316
		}
1317
672
		r = bmalloc(sizeof(*r));
1318
672
		r->scale = scale;
1319
672
		r->number = y;
1320
672
		BN_free(x);
1321
672
		BN_CTX_free(ctx);
1322
672
		push_number(r);
1323
	}
1324
1325
672
	free_number(n);
1326
1344
}
1327
1328
static void
1329
not(void)
1330
{
1331
	struct number	*a;
1332
1333
	a = pop_number();
1334
	if (a == NULL)
1335
		return;
1336
	a->scale = 0;
1337
	bn_check(BN_set_word(a->number, BN_get_word(a->number) ? 0 : 1));
1338
	push_number(a);
1339
}
1340
1341
static void
1342
equal(void)
1343
{
1344
84272
	compare(BCODE_EQUAL);
1345
42136
}
1346
1347
static void
1348
equal_numbers(void)
1349
{
1350
	struct number *a, *b, *r;
1351
1352
	a = pop_number();
1353
	if (a == NULL)
1354
		return;
1355
	b = pop_number();
1356
	if (b == NULL) {
1357
		push_number(a);
1358
		return;
1359
	}
1360
	r = new_number();
1361
	bn_check(BN_set_word(r->number,
1362
	    compare_numbers(BCODE_EQUAL, a, b) ? 1 : 0));
1363
	push_number(r);
1364
}
1365
1366
static void
1367
less_numbers(void)
1368
{
1369
	struct number *a, *b, *r;
1370
1371
	a = pop_number();
1372
	if (a == NULL)
1373
		return;
1374
	b = pop_number();
1375
	if (b == NULL) {
1376
		push_number(a);
1377
		return;
1378
	}
1379
	r = new_number();
1380
	bn_check(BN_set_word(r->number,
1381
	    compare_numbers(BCODE_LESS, a, b) ? 1 : 0));
1382
	push_number(r);
1383
}
1384
1385
static void
1386
lesseq_numbers(void)
1387
{
1388
	struct number *a, *b, *r;
1389
1390
	a = pop_number();
1391
	if (a == NULL)
1392
		return;
1393
	b = pop_number();
1394
	if (b == NULL) {
1395
		push_number(a);
1396
		return;
1397
	}
1398
	r = new_number();
1399
	bn_check(BN_set_word(r->number,
1400
	    compare_numbers(BCODE_NOT_GREATER, a, b) ? 1 : 0));
1401
	push_number(r);
1402
}
1403
1404
static void
1405
not_equal(void)
1406
{
1407
3080
	compare(BCODE_NOT_EQUAL);
1408
1540
}
1409
1410
static void
1411
less(void)
1412
{
1413
4032
	compare(BCODE_LESS);
1414
2016
}
1415
1416
static void
1417
not_compare(void)
1418
{
1419

5544
	switch (readch()) {
1420
	case '<':
1421
392
		not_less();
1422
392
		break;
1423
	case '>':
1424
840
		not_greater();
1425
840
		break;
1426
	case '=':
1427
1540
		not_equal();
1428
1540
		break;
1429
	default:
1430
		unreadch();
1431
		(void)fprintf(stderr, "! command is deprecated\n");
1432
		break;
1433
	}
1434
2772
}
1435
1436
static void
1437
not_less(void)
1438
{
1439
784
	compare(BCODE_NOT_LESS);
1440
392
}
1441
1442
static void
1443
greater(void)
1444
{
1445
9352
	compare(BCODE_GREATER);
1446
4676
}
1447
1448
static void
1449
not_greater(void)
1450
{
1451
1680
	compare(BCODE_NOT_GREATER);
1452
840
}
1453
1454
static bool
1455
compare_numbers(enum bcode_compare type, struct number *a, struct number *b)
1456
{
1457
	u_int	scale;
1458
	int	cmp;
1459
1460
103200
	scale = max(a->scale, b->scale);
1461
1462
51600
	if (scale > a->scale)
1463
12836
		normalize(a, scale);
1464
38764
	else if (scale > b->scale)
1465
		normalize(b, scale);
1466
1467
51600
	cmp = BN_cmp(a->number, b->number);
1468
1469
51600
	free_number(a);
1470
51600
	free_number(b);
1471
1472

51600
	switch (type) {
1473
	case BCODE_EQUAL:
1474
42136
		return cmp == 0;
1475
	case BCODE_NOT_EQUAL:
1476
1540
		return cmp != 0;
1477
	case BCODE_LESS:
1478
2016
		return cmp < 0;
1479
	case BCODE_NOT_LESS:
1480
392
		return cmp >= 0;
1481
	case BCODE_GREATER:
1482
4676
		return cmp > 0;
1483
	case BCODE_NOT_GREATER:
1484
840
		return cmp <= 0;
1485
	}
1486
	return false;
1487
51600
}
1488
1489
static void
1490
compare(enum bcode_compare type)
1491
{
1492
	int		idx, elseidx;
1493
	struct number	*a, *b;
1494
	bool		ok;
1495
	struct value	*v;
1496
1497
	elseidx = NO_ELSE;
1498
103200
	idx = readreg();
1499
51600
	if (readch() == 'e')
1500
196
		elseidx = readreg();
1501
	else
1502
51404
		unreadch();
1503
1504
51600
	a = pop_number();
1505
51600
	if (a == NULL)
1506
		return;
1507
51600
	b = pop_number();
1508
51600
	if (b == NULL) {
1509
		push_number(a);
1510
		return;
1511
	}
1512
1513
51600
	ok = compare_numbers(type, a, b);
1514
1515
51600
	if (!ok && elseidx != NO_ELSE)
1516
140
		idx = elseidx;
1517
1518

127760
	if (idx >= 0 && (ok || (!ok && elseidx != NO_ELSE))) {
1519
27180
		v = stack_tos(&bmachine.reg[idx]);
1520
27180
		if (v == NULL)
1521
			warnx("register '%c' (0%o) is empty", idx, idx);
1522
		else {
1523

75924
			switch(v->type) {
1524
			case BCODE_NONE:
1525
				warnx("register '%c' (0%o) is empty", idx, idx);
1526
				break;
1527
			case BCODE_NUMBER:
1528
				warn("eval called with non-string argument");
1529
				break;
1530
			case BCODE_STRING:
1531
27180
				eval_string(bstrdup(v->u.string));
1532
27180
				break;
1533
			}
1534
		}
1535
	}
1536
103200
}
1537
1538
1539
static void
1540
nop(void)
1541
{
1542
563960
}
1543
1544
static void
1545
quit(void)
1546
{
1547
4152
	if (bmachine.readsp < 2)
1548
		exit(0);
1549
	src_free();
1550
	bmachine.readsp--;
1551
	src_free();
1552
	bmachine.readsp--;
1553
}
1554
1555
static void
1556
quitN(void)
1557
{
1558
	struct number	*n;
1559
	u_long		i;
1560
1561
7504
	n = pop_number();
1562
3752
	if (n == NULL)
1563
		return;
1564
3752
	i = get_ulong(n);
1565
3752
	free_number(n);
1566
3752
	if (i == BN_MASK2 || i == 0)
1567
		warnx("Q command requires a number >= 1");
1568
3752
	else if (bmachine.readsp < i)
1569
		warnx("Q command argument exceeded string execution depth");
1570
	else {
1571
28280
		while (i-- > 0) {
1572
10388
			src_free();
1573
10388
			bmachine.readsp--;
1574
		}
1575
	}
1576
7504
}
1577
1578
static void
1579
skipN(void)
1580
{
1581
	struct number	*n;
1582
	u_long		i;
1583
1584
	n = pop_number();
1585
	if (n == NULL)
1586
		return;
1587
	i = get_ulong(n);
1588
	if (i == BN_MASK2)
1589
		warnx("J command requires a number >= 0");
1590
	else if (i > 0 && bmachine.readsp < i)
1591
		warnx("J command argument exceeded string execution depth");
1592
	else {
1593
		while (i-- > 0) {
1594
			src_free();
1595
			bmachine.readsp--;
1596
		}
1597
		skip_until_mark();
1598
	}
1599
}
1600
1601
static void
1602
skip_until_mark(void)
1603
{
1604
	int ch;
1605
1606
	for (;;) {
1607
		ch = readch();
1608
		switch (ch) {
1609
		case 'M':
1610
			return;
1611
		case EOF:
1612
			errx(1, "mark not found");
1613
			return;
1614
		case 'l':
1615
		case 'L':
1616
		case 's':
1617
		case 'S':
1618
		case ':':
1619
		case ';':
1620
		case '<':
1621
		case '>':
1622
		case '=':
1623
			(void)readreg();
1624
			if (readch() == 'e')
1625
				(void)readreg();
1626
			else
1627
				unreadch();
1628
			break;
1629
		case '[':
1630
			free(read_string(&bmachine.readstack[bmachine.readsp]));
1631
			break;
1632
		case '!':
1633
			switch (ch = readch()) {
1634
				case '<':
1635
				case '>':
1636
				case '=':
1637
					(void)readreg();
1638
					if (readch() == 'e')
1639
						(void)readreg();
1640
					else
1641
						unreadch();
1642
					break;
1643
				default:
1644
					free(readline());
1645
					break;
1646
			}
1647
			break;
1648
		default:
1649
			break;
1650
		}
1651
	}
1652
}
1653
1654
static void
1655
parse_number(void)
1656
{
1657
320664
	unreadch();
1658
320664
	push_number(readnumber(&bmachine.readstack[bmachine.readsp],
1659
160332
	    bmachine.ibase));
1660
160332
}
1661
1662
static void
1663
unknown(void)
1664
{
1665
	int ch = bmachine.readstack[bmachine.readsp].lastchar;
1666
	warnx("%c (0%o) is unimplemented", ch, ch);
1667
}
1668
1669
static void
1670
eval_string(char *p)
1671
{
1672
	int ch;
1673
1674
61864
	if (bmachine.readsp > 0) {
1675
		/* Check for tail call. Do not recurse in that case. */
1676
28860
		ch = readch();
1677
28860
		if (ch == EOF) {
1678
17904
			src_free();
1679
17904
			src_setstring(&bmachine.readstack[bmachine.readsp], p);
1680
17904
			return;
1681
		} else
1682
10956
			unreadch();
1683
10956
	}
1684
13028
	if (bmachine.readsp == bmachine.readstack_sz - 1) {
1685
		size_t newsz = bmachine.readstack_sz * 2;
1686
		struct source *stack;
1687
		stack = reallocarray(bmachine.readstack, newsz,
1688
		    sizeof(struct source));
1689
		if (stack == NULL)
1690
			err(1, "recursion too deep");
1691
		bmachine.readstack_sz = newsz;
1692
		bmachine.readstack = stack;
1693
	}
1694
13028
	src_setstring(&bmachine.readstack[++bmachine.readsp], p);
1695
43960
}
1696
1697
static void
1698
eval_line(void)
1699
{
1700
	/* Always read from stdin */
1701
	struct source	in;
1702
	char		*p;
1703
1704
	clearerr(stdin);
1705
	src_setstream(&in, stdin);
1706
	p = (*in.vtable->readline)(&in);
1707
	eval_string(p);
1708
}
1709
1710
static void
1711
eval_tos(void)
1712
{
1713
	char *p;
1714
1715
7504
	p = pop_string();
1716
3752
	if (p != NULL)
1717
3752
		eval_string(p);
1718
3752
}
1719
1720
void
1721
eval(void)
1722
{
1723
	int	ch;
1724
1725
1452288
	for (;;) {
1726
1452852
		ch = readch();
1727
1452852
		if (ch == EOF) {
1728
2640
			if (bmachine.readsp == 0)
1729
				return;
1730
2640
			src_free();
1731
2640
			bmachine.readsp--;
1732
2640
			continue;
1733
		}
1734
1450212
		if (bmachine.interrupted) {
1735
			if (bmachine.readsp > 0) {
1736
				src_free();
1737
				bmachine.readsp--;
1738
				continue;
1739
			} else
1740
				bmachine.interrupted = false;
1741
		}
1742
#ifdef DEBUGGING
1743
		(void)fprintf(stderr, "# %c\n", ch);
1744
		stack_print(stderr, &bmachine.stack, "* ",
1745
		    bmachine.obase);
1746
		(void)fprintf(stderr, "%zd =>\n", bmachine.readsp);
1747
#endif
1748
1749
1450212
		if (0 <= ch && ch < UCHAR_MAX)
1750
1450212
			(*jump_table[ch])();
1751
		else
1752
			warnx("internal error: opcode %d", ch);
1753
1754
#ifdef DEBUGGING
1755
		stack_print(stderr, &bmachine.stack, "* ",
1756
		    bmachine.obase);
1757
		(void)fprintf(stderr, "%zd ==\n", bmachine.readsp);
1758
#endif
1759
	}
1760
}