xref: /freebsd/contrib/bc/src/program.c (revision dbf05458e3bd8c46f5e49918593557293a29d41a)
1 /*
2  * *****************************************************************************
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  *
6  * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * * Redistributions of source code must retain the above copyright notice, this
12  *   list of conditions and the following disclaimer.
13  *
14  * * Redistributions in binary form must reproduce the above copyright notice,
15  *   this list of conditions and the following disclaimer in the documentation
16  *   and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * *****************************************************************************
31  *
32  * Code to execute bc programs.
33  *
34  */
35 
36 #include <assert.h>
37 #include <stdbool.h>
38 #include <string.h>
39 
40 #include <setjmp.h>
41 
42 #include <signal.h>
43 
44 #include <time.h>
45 
46 #include <read.h>
47 #include <parse.h>
48 #include <program.h>
49 #include <vm.h>
50 
51 /**
52  * Quickly sets the const and strs vector pointers in the program. This is a
53  * convenience function.
54  * @param p  The program.
55  * @param f  The new function.
56  */
57 static inline void bc_program_setVecs(BcProgram *p, BcFunc *f) {
58 	BC_SIG_ASSERT_LOCKED;
59 	p->consts = &f->consts;
60 	p->strs = &f->strs;
61 }
62 
63 /**
64  * Does a type check for something that expects a number.
65  * @param r  The result that will be checked.
66  * @param n  The result's number.
67  */
68 static inline void bc_program_type_num(BcResult *r, BcNum *n) {
69 
70 #if BC_ENABLED
71 
72 	// This should have already been taken care of.
73 	assert(r->t != BC_RESULT_VOID);
74 
75 #endif // BC_ENABLED
76 
77 	if (BC_ERR(!BC_PROG_NUM(r, n))) bc_err(BC_ERR_EXEC_TYPE);
78 }
79 
80 #if BC_ENABLED
81 
82 /**
83  * Does a type check.
84  * @param r  The result to check.
85  * @param t  The type that the result should be.
86  */
87 static void bc_program_type_match(BcResult *r, BcType t) {
88 	if (BC_ERR((r->t != BC_RESULT_ARRAY) != (!t))) bc_err(BC_ERR_EXEC_TYPE);
89 }
90 #endif // BC_ENABLED
91 
92 /**
93  * Pulls an index out of a bytecode vector and updates the index into the vector
94  * to point to the spot after the index. For more details on bytecode indices,
95  * see the development manual (manuals/development.md#bytecode-indices).
96  * @param code  The bytecode vector.
97  * @param bgn   An in/out parameter; the index into the vector that will be
98  *              updated.
99  * @return      The index at @a bgn in the bytecode vector.
100  */
101 static size_t bc_program_index(const char *restrict code, size_t *restrict bgn)
102 {
103 	uchar amt = (uchar) code[(*bgn)++], i = 0;
104 	size_t res = 0;
105 
106 	for (; i < amt; ++i, ++(*bgn)) {
107 		size_t temp = ((size_t) ((int) (uchar) code[*bgn]) & UCHAR_MAX);
108 		res |= (temp << (i * CHAR_BIT));
109 	}
110 
111 	return res;
112 }
113 
114 /**
115  * Returns a string from a result and its number.
116  * @param p  The program.
117  * @param n  The number tied to the result.
118  * @return   The string corresponding to the result and number.
119  */
120 static char* bc_program_string(BcProgram *p, const BcNum *n) {
121 	BcFunc *f = bc_vec_item(&p->fns, n->rdx);
122 	return *((char**) bc_vec_item(&f->strs, n->scale));
123 }
124 
125 #if BC_ENABLED
126 
127 /**
128  * Prepares the globals for a function call. This is only called when global
129  * stacks are on because it pushes a copy of the current globals onto each of
130  * their respective stacks.
131  * @param p  The program.
132  */
133 static void bc_program_prepGlobals(BcProgram *p) {
134 
135 	size_t i;
136 
137 	for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i)
138 		bc_vec_push(p->globals_v + i, p->globals + i);
139 
140 #if BC_ENABLE_EXTRA_MATH
141 	bc_rand_push(&p->rng);
142 #endif // BC_ENABLE_EXTRA_MATH
143 }
144 
145 /**
146  * Pops globals stacks on returning from a function, or in the case of reset,
147  * pops all but one item on each global stack.
148  * @param p      The program.
149  * @param reset  True if all but one item on each stack should be popped, false
150  *               otherwise.
151  */
152 static void bc_program_popGlobals(BcProgram *p, bool reset) {
153 
154 	size_t i;
155 
156 	BC_SIG_ASSERT_LOCKED;
157 
158 	for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) {
159 		BcVec *v = p->globals_v + i;
160 		bc_vec_npop(v, reset ? v->len - 1 : 1);
161 		p->globals[i] = BC_PROG_GLOBAL(v);
162 	}
163 
164 #if BC_ENABLE_EXTRA_MATH
165 	bc_rand_pop(&p->rng, reset);
166 #endif // BC_ENABLE_EXTRA_MATH
167 }
168 
169 /**
170  * Derefeneces an array reference and returns a pointer to the real array.
171  * @param p    The program.
172  * @param vec  The reference vector.
173  * @return     A pointer to the desired array.
174  */
175 static BcVec* bc_program_dereference(const BcProgram *p, BcVec *vec) {
176 
177 	BcVec *v;
178 	size_t vidx, nidx, i = 0;
179 
180 	// We want to be sure we have a reference vector.
181 	assert(vec->size == sizeof(uchar));
182 
183 	// Get the index of the vector in arrs, then the index of the original
184 	// referenced vector.
185 	vidx = bc_program_index(vec->v, &i);
186 	nidx = bc_program_index(vec->v, &i);
187 
188 	v = bc_vec_item(bc_vec_item(&p->arrs, vidx), nidx);
189 
190 	// We want to be sure we do *not* have a reference vector.
191 	assert(v->size != sizeof(uchar));
192 
193 	return v;
194 }
195 #endif // BC_ENABLED
196 
197 /**
198  * Creates a BcNum from a BcBigDig and pushes onto the results stack. This is a
199  * convenience function.
200  * @param p     The program.
201  * @param dig   The BcBigDig to push onto the results stack.
202  * @param type  The type that the pushed result should be.
203  */
204 static void bc_program_pushBigdig(BcProgram *p, BcBigDig dig, BcResultType type)
205 {
206 	BcResult res;
207 
208 	res.t = type;
209 
210 	BC_SIG_LOCK;
211 
212 	bc_num_createFromBigdig(&res.d.n, dig);
213 	bc_vec_push(&p->results, &res);
214 
215 	BC_SIG_UNLOCK;
216 }
217 
218 size_t bc_program_addString(BcProgram *p, const char *str, size_t fidx) {
219 
220 	BcFunc *f;
221 	char **str_ptr;
222 	BcVec *slabs;
223 
224 	BC_SIG_ASSERT_LOCKED;
225 
226 	// Push an empty string on the proper vector.
227 	f = bc_vec_item(&p->fns, fidx);
228 	str_ptr = bc_vec_pushEmpty(&f->strs);
229 
230 	// Figure out which slab vector to use.
231 	slabs = fidx == BC_PROG_MAIN || fidx == BC_PROG_READ ?
232 	        &vm.main_slabs : &vm.other_slabs;
233 
234 	*str_ptr = bc_slabvec_strdup(slabs, str);
235 
236 	return f->strs.len - 1;
237 }
238 
239 size_t bc_program_search(BcProgram *p, const char *id, bool var) {
240 
241 	BcVec *v, *map;
242 	size_t i;
243 
244 	BC_SIG_ASSERT_LOCKED;
245 
246 	// Grab the right vector and map.
247 	v = var ? &p->vars : &p->arrs;
248 	map = var ? &p->var_map : &p->arr_map;
249 
250 	// We do an insert because the variable might not exist yet. This is because
251 	// the parser calls this function. If the insert succeeds, we create a stack
252 	// for the variable/array. But regardless, bc_map_insert() gives us the
253 	// index of the item in i.
254 	if (bc_map_insert(map, id, v->len, &i)) {
255 		BcVec *temp = bc_vec_pushEmpty(v);
256 		bc_array_init(temp, var);
257 	}
258 
259 	return ((BcId*) bc_vec_item(map, i))->idx;
260 }
261 
262 /**
263  * Returns the correct variable or array stack for the type.
264  * @param p     The program.
265  * @param idx   The index of the variable or array in the variable or array
266  *              vector.
267  * @param type  The type of vector to return.
268  * @return      A pointer to the variable or array stack.
269  */
270 static inline BcVec* bc_program_vec(const BcProgram *p, size_t idx, BcType type)
271 {
272 	const BcVec *v = (type == BC_TYPE_VAR) ? &p->vars : &p->arrs;
273 	return bc_vec_item(v, idx);
274 }
275 
276 /**
277  * Returns a pointer to the BcNum corresponding to the result. There is one
278  * case, however, where this returns a pointer to a BcVec: if the type of the
279  * result is array. In that case, the pointer is casted to a pointer to BcNum,
280  * but is never used. The function that calls this expecting an array casts the
281  * pointer back. This function is called a lot and needs to be as fast as
282  * possible.
283  * @param p  The program.
284  * @param r  The result whose number will be returned.
285  * @return   The BcNum corresponding to the result.
286  */
287 static BcNum* bc_program_num(BcProgram *p, BcResult *r) {
288 
289 	BcNum *n;
290 
291 #ifdef _WIN32
292 	// Windows made it an error to not initialize this, so shut it up.
293 	// I don't want to do this on other platforms because this procedure
294 	// is one of the most heavily-used, and eliminating the initialization
295 	// is a performance win.
296 	n = NULL;
297 #endif // _WIN32
298 
299 	switch (r->t) {
300 
301 		case BC_RESULT_STR:
302 		case BC_RESULT_TEMP:
303 		case BC_RESULT_IBASE:
304 		case BC_RESULT_SCALE:
305 		case BC_RESULT_OBASE:
306 #if BC_ENABLE_EXTRA_MATH
307 		case BC_RESULT_SEED:
308 #endif // BC_ENABLE_EXTRA_MATH
309 		{
310 			n = &r->d.n;
311 			break;
312 		}
313 
314 		case BC_RESULT_VAR:
315 		case BC_RESULT_ARRAY:
316 		case BC_RESULT_ARRAY_ELEM:
317 		{
318 			BcVec *v;
319 			BcType type = (r->t == BC_RESULT_VAR) ? BC_TYPE_VAR : BC_TYPE_ARRAY;
320 
321 			// Get the correct variable or array vector.
322 			v = bc_program_vec(p, r->d.loc.loc, type);
323 
324 			// Surprisingly enough, the hard case is *not* returning an array;
325 			// it's returning an array element. This is because we have to dig
326 			// deeper to get *to* the element. That's what the code inside this
327 			// if statement does.
328 			if (r->t == BC_RESULT_ARRAY_ELEM) {
329 
330 				size_t idx = r->d.loc.idx;
331 
332 				v = bc_vec_top(v);
333 
334 #if BC_ENABLED
335 				// If this is true, we have a reference vector, so dereference
336 				// it. The reason we don't need to worry about it for returning
337 				// a straight array is because we only care about references
338 				// when we access elements of an array that is a reference. That
339 				// is this code, so in essence, this line takes care of arrays
340 				// as well.
341 				if (v->size == sizeof(uchar)) v = bc_program_dereference(p, v);
342 #endif // BC_ENABLED
343 
344 				// We want to be sure we got a valid array of numbers.
345 				assert(v->size == sizeof(BcNum));
346 
347 				// The bc spec says that if an element is accessed that does not
348 				// exist, it should be preinitialized to 0. Well, if we access
349 				// an element *way* out there, we have to preinitialize all
350 				// elements between the current last element and the actual
351 				// accessed element.
352 				if (v->len <= idx) {
353 					BC_SIG_LOCK;
354 					bc_array_expand(v, bc_vm_growSize(idx, 1));
355 					BC_SIG_UNLOCK;
356 				}
357 
358 				n = bc_vec_item(v, idx);
359 			}
360 			// This is either a number (for a var) or an array (for an array).
361 			// Because bc_vec_top() returns a void*, we don't need to cast.
362 			else n = bc_vec_top(v);
363 
364 			break;
365 		}
366 
367 		case BC_RESULT_ZERO:
368 		{
369 			n = &vm.zero;
370 			break;
371 		}
372 
373 		case BC_RESULT_ONE:
374 		{
375 			n = &vm.one;
376 			break;
377 		}
378 
379 #if BC_ENABLED
380 		// We should never get here; this is taken care of earlier because a
381 		// result is expected.
382 		case BC_RESULT_VOID:
383 #ifndef NDEBUG
384 		{
385 			abort();
386 		}
387 #endif // NDEBUG
388 		// Fallthrough
389 		case BC_RESULT_LAST:
390 		{
391 			n = &p->last;
392 			break;
393 		}
394 #endif // BC_ENABLED
395 	}
396 
397 	return n;
398 }
399 
400 /**
401  * Prepares an operand for use.
402  * @param p    The program.
403  * @param r    An out parameter; this is set to the pointer to the result that
404  *             we care about.
405  * @param n    An out parameter; this is set to the pointer to the number that
406  *             we care about.
407  * @param idx  The index of the result from the top of the results stack.
408  */
409 static void bc_program_operand(BcProgram *p, BcResult **r,
410                                BcNum **n, size_t idx)
411 {
412 	*r = bc_vec_item_rev(&p->results, idx);
413 
414 #if BC_ENABLED
415 	if (BC_ERR((*r)->t == BC_RESULT_VOID)) bc_err(BC_ERR_EXEC_VOID_VAL);
416 #endif // BC_ENABLED
417 
418 	*n = bc_program_num(p, *r);
419 }
420 
421 /**
422  * Prepares the operands of a binary operator.
423  * @param p    The program.
424  * @param l    An out parameter; this is set to the pointer to the result for
425  *             the left operand.
426  * @param ln   An out parameter; this is set to the pointer to the number for
427  *             the left operand.
428  * @param r    An out parameter; this is set to the pointer to the result for
429  *             the right operand.
430  * @param rn   An out parameter; this is set to the pointer to the number for
431  *             the right operand.
432  * @param idx  The starting index where the operands are in the results stack,
433  *             starting from the top.
434  */
435 static void bc_program_binPrep(BcProgram *p, BcResult **l, BcNum **ln,
436                                BcResult **r, BcNum **rn, size_t idx)
437 {
438 	BcResultType lt;
439 
440 	assert(p != NULL && l != NULL && ln != NULL && r != NULL && rn != NULL);
441 
442 #ifndef BC_PROG_NO_STACK_CHECK
443 	// Check the stack for dc.
444 	if (BC_IS_DC) {
445 		if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 2)))
446 			bc_err(BC_ERR_EXEC_STACK);
447 	}
448 #endif // BC_PROG_NO_STACK_CHECK
449 
450 	assert(BC_PROG_STACK(&p->results, idx + 2));
451 
452 	// Get the operands.
453 	bc_program_operand(p, l, ln, idx + 1);
454 	bc_program_operand(p, r, rn, idx);
455 
456 	lt = (*l)->t;
457 
458 #if BC_ENABLED
459 	// bc_program_operand() checked these for us.
460 	assert(lt != BC_RESULT_VOID && (*r)->t != BC_RESULT_VOID);
461 #endif // BC_ENABLED
462 
463 	// We run this again under these conditions in case any vector has been
464 	// reallocated out from under the BcNums or arrays we had. In other words,
465 	// this is to fix pointer invalidation.
466 	if (lt == (*r)->t && (lt == BC_RESULT_VAR || lt == BC_RESULT_ARRAY_ELEM))
467 		*ln = bc_program_num(p, *l);
468 
469 	if (BC_ERR(lt == BC_RESULT_STR)) bc_err(BC_ERR_EXEC_TYPE);
470 }
471 
472 /**
473  * Prepares the operands of a binary operator and type checks them. This is
474  * separate from bc_program_binPrep() because some places want this, others want
475  * bc_program_binPrep().
476  * @param p    The program.
477  * @param l    An out parameter; this is set to the pointer to the result for
478  *             the left operand.
479  * @param ln   An out parameter; this is set to the pointer to the number for
480  *             the left operand.
481  * @param r    An out parameter; this is set to the pointer to the result for
482  *             the right operand.
483  * @param rn   An out parameter; this is set to the pointer to the number for
484  *             the right operand.
485  * @param idx  The starting index where the operands are in the results stack,
486  *             starting from the top.
487  */
488 static void bc_program_binOpPrep(BcProgram *p, BcResult **l, BcNum **ln,
489                                  BcResult **r, BcNum **rn, size_t idx)
490 {
491 	bc_program_binPrep(p, l, ln, r, rn, idx);
492 	bc_program_type_num(*l, *ln);
493 	bc_program_type_num(*r, *rn);
494 }
495 
496 /**
497  * Prepares the operands of an assignment operator.
498  * @param p   The program.
499  * @param l   An out parameter; this is set to the pointer to the result for the
500  *            left operand.
501  * @param ln  An out parameter; this is set to the pointer to the number for the
502  *            left operand.
503  * @param r   An out parameter; this is set to the pointer to the result for the
504  *            right operand.
505  * @param rn  An out parameter; this is set to the pointer to the number for the
506  *            right operand.
507  */
508 static void bc_program_assignPrep(BcProgram *p, BcResult **l, BcNum **ln,
509                                   BcResult **r, BcNum **rn)
510 {
511 	BcResultType lt, min;
512 
513 	// This is the min non-allowable result type. dc allows strings.
514 	min = BC_RESULT_TEMP - ((unsigned int) (BC_IS_BC));
515 
516 	// Prepare the operands.
517 	bc_program_binPrep(p, l, ln, r, rn, 0);
518 
519 	lt = (*l)->t;
520 
521 	// Typecheck the left.
522 	if (BC_ERR(lt >= min && lt <= BC_RESULT_ONE)) bc_err(BC_ERR_EXEC_TYPE);
523 
524 	// Strings can be assigned to variables. We are already good if we are
525 	// assigning a string.
526 	bool good = ((*r)->t == BC_RESULT_STR && lt <= BC_RESULT_ARRAY_ELEM);
527 
528 	assert(BC_PROG_STR(*rn) || (*r)->t != BC_RESULT_STR);
529 
530 	// If not, type check for a number.
531 	if (!good) bc_program_type_num(*r, *rn);
532 }
533 
534 /**
535  * Prepares a single operand and type checks it. This is separate from
536  * bc_program_operand() because different places want one or the other.
537  * @param p    The program.
538  * @param r    An out parameter; this is set to the pointer to the result that
539  *             we care about.
540  * @param n    An out parameter; this is set to the pointer to the number that
541  *             we care about.
542  * @param idx  The index of the result from the top of the results stack.
543  */
544 static void bc_program_prep(BcProgram *p, BcResult **r, BcNum **n, size_t idx) {
545 
546 	assert(p != NULL && r != NULL && n != NULL);
547 
548 #ifndef BC_PROG_NO_STACK_CHECK
549 	// Check the stack for dc.
550 	if (BC_IS_DC) {
551 		if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 1)))
552 			bc_err(BC_ERR_EXEC_STACK);
553 	}
554 #endif // BC_PROG_NO_STACK_CHECK
555 
556 	assert(BC_PROG_STACK(&p->results, idx + 1));
557 
558 	bc_program_operand(p, r, n, idx);
559 
560 	// dc does not allow strings in this case.
561 	bc_program_type_num(*r, *n);
562 }
563 
564 /**
565  * Prepares and returns a clean result for the result of an operation.
566  * @param p  The program.
567  * @return   A clean result.
568  */
569 static BcResult* bc_program_prepResult(BcProgram *p) {
570 
571 	BcResult *res = bc_vec_pushEmpty(&p->results);
572 
573 	bc_result_clear(res);
574 
575 	return res;
576 }
577 
578 /**
579  * Prepares a constant for use. This parses the constant into a number and then
580  * pushes that number onto the results stack.
581  * @param p     The program.
582  * @param code  The bytecode vector that we will pull the index of the constant
583  *              from.
584  * @param bgn   An in/out parameter; marks the start of the index in the
585  *              bytecode vector and will be updated to point to after the index.
586  */
587 static void bc_program_const(BcProgram *p, const char *code, size_t *bgn) {
588 
589 	// I lied. I actually push the result first. I can do this because the
590 	// result will be popped on error. I also get the constant itself.
591 	BcResult *r = bc_program_prepResult(p);
592 	BcConst *c = bc_vec_item(p->consts, bc_program_index(code, bgn));
593 	BcBigDig base = BC_PROG_IBASE(p);
594 
595 	// Only reparse if the base changed.
596 	if (c->base != base) {
597 
598 		// Allocate if we haven't yet.
599 		if (c->num.num == NULL) {
600 			BC_SIG_LOCK;
601 			bc_num_init(&c->num, BC_NUM_RDX(strlen(c->val)));
602 			BC_SIG_UNLOCK;
603 		}
604 
605 		// bc_num_parse() should only do operations that cannot fail.
606 		bc_num_parse(&c->num, c->val, base);
607 
608 		c->base = base;
609 	}
610 
611 	BC_SIG_LOCK;
612 
613 	bc_num_createCopy(&r->d.n, &c->num);
614 
615 	BC_SIG_UNLOCK;
616 }
617 
618 /**
619  * Executes a binary operator operation.
620  * @param p     The program.
621  * @param inst  The instruction corresponding to the binary operator to execute.
622  */
623 static void bc_program_op(BcProgram *p, uchar inst) {
624 
625 	BcResult *opd1, *opd2, *res;
626 	BcNum *n1, *n2;
627 	size_t idx = inst - BC_INST_POWER;
628 
629 	res = bc_program_prepResult(p);
630 
631 	bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, 1);
632 
633 	BC_SIG_LOCK;
634 
635 	// Initialize the number with enough space, using the correct
636 	// BcNumBinaryOpReq function. This looks weird because it is executing an
637 	// item of an array. Rest assured that item is a function.
638 	bc_num_init(&res->d.n, bc_program_opReqs[idx](n1, n2, BC_PROG_SCALE(p)));
639 
640 	BC_SIG_UNLOCK;
641 
642 	assert(BC_NUM_RDX_VALID(n1));
643 	assert(BC_NUM_RDX_VALID(n2));
644 
645 	// Run the operation. This also executes an item of an array.
646 	bc_program_ops[idx](n1, n2, &res->d.n, BC_PROG_SCALE(p));
647 
648 	bc_program_retire(p, 1, 2);
649 }
650 
651 /**
652  * Executes a read() or ? command.
653  * @param p  The program.
654  */
655 static void bc_program_read(BcProgram *p) {
656 
657 	BcStatus s;
658 	BcInstPtr ip;
659 	size_t i;
660 	const char* file;
661 	bool is_stdin;
662 	BcFunc *f = bc_vec_item(&p->fns, BC_PROG_READ);
663 
664 	// If we are already executing a read, that is an error. So look for a read
665 	// and barf.
666 	for (i = 0; i < p->stack.len; ++i) {
667 		BcInstPtr *ip_ptr = bc_vec_item(&p->stack, i);
668 		if (ip_ptr->func == BC_PROG_READ) bc_err(BC_ERR_EXEC_REC_READ);
669 	}
670 
671 	BC_SIG_LOCK;
672 
673 	// Save the filename because we are going to overwrite it.
674 	file = vm.file;
675 	is_stdin = vm.is_stdin;
676 
677 	// It is a parse error if there needs to be more than one line, so we unset
678 	// this to tell the lexer to not request more. We set it back later.
679 	vm.is_stdin = false;
680 
681 	if (!BC_PARSE_IS_INITED(&vm.read_prs, p)) {
682 
683 		// We need to parse, but we don't want to use the existing parser
684 		// because it has state it needs to keep. (It could have a partial parse
685 		// state.) So we create a new parser. This parser is in the BcVm struct
686 		// so that it is not local, which means that a longjmp() could change
687 		// it.
688 		bc_parse_init(&vm.read_prs, p, BC_PROG_READ);
689 
690 		// We need a separate input buffer; that's why it is also in the BcVm
691 		// struct.
692 		bc_vec_init(&vm.read_buf, sizeof(char), BC_DTOR_NONE);
693 	}
694 	// This needs to be updated because the parser could have been used
695 	// somewhere else
696 	else bc_parse_updateFunc(&vm.read_prs, BC_PROG_READ);
697 
698 	BC_SETJMP_LOCKED(exec_err);
699 
700 	BC_SIG_UNLOCK;
701 
702 	// Set up the lexer and the read function.
703 	bc_lex_file(&vm.read_prs.l, bc_program_stdin_name);
704 	bc_vec_popAll(&f->code);
705 
706 	// Read a line.
707 	if (!BC_R) s = bc_read_line(&vm.read_buf, "");
708 	else s = bc_read_line(&vm.read_buf, BC_IS_BC ? "read> " : "?> ");
709 
710 	// We should *not* have run into EOF.
711 	if (s == BC_STATUS_EOF) bc_err(BC_ERR_EXEC_READ_EXPR);
712 
713 	// Parse *one* expression.
714 	bc_parse_text(&vm.read_prs, vm.read_buf.v, false);
715 	BC_SIG_LOCK;
716 	vm.expr(&vm.read_prs, BC_PARSE_NOREAD | BC_PARSE_NEEDVAL);
717 	BC_SIG_UNLOCK;
718 
719 	// We *must* have a valid expression. A semicolon cannot end an expression,
720 	// although EOF can.
721 	if (BC_ERR(vm.read_prs.l.t != BC_LEX_NLINE &&
722 	           vm.read_prs.l.t != BC_LEX_EOF))
723 	{
724 		bc_err(BC_ERR_EXEC_READ_EXPR);
725 	}
726 
727 #if BC_ENABLED
728 	// Push on the globals stack if necessary.
729 	if (BC_G) bc_program_prepGlobals(p);
730 #endif // BC_ENABLED
731 
732 	// Set up a new BcInstPtr.
733 	ip.func = BC_PROG_READ;
734 	ip.idx = 0;
735 	ip.len = p->results.len;
736 
737 	// Update this pointer, just in case.
738 	f = bc_vec_item(&p->fns, BC_PROG_READ);
739 
740 	// We want a return instruction to simplify things.
741 	bc_vec_pushByte(&f->code, vm.read_ret);
742 
743 	// This lock is here to make sure dc's tail calls are the same length.
744 	BC_SIG_LOCK;
745 	bc_vec_push(&p->stack, &ip);
746 
747 #if DC_ENABLED
748 	// We need a new tail call entry for dc.
749 	if (BC_IS_DC) {
750 		size_t temp = 0;
751 		bc_vec_push(&p->tail_calls, &temp);
752 	}
753 #endif // DC_ENABLED
754 
755 exec_err:
756 	BC_SIG_MAYLOCK;
757 	vm.is_stdin = is_stdin;
758 	vm.file = file;
759 	BC_LONGJMP_CONT;
760 }
761 
762 #if BC_ENABLE_EXTRA_MATH
763 
764 /**
765  * Execute a rand().
766  * @param p  The program.
767  */
768 static void bc_program_rand(BcProgram *p) {
769 
770 	BcRand rand = bc_rand_int(&p->rng);
771 
772 	bc_program_pushBigdig(p, (BcBigDig) rand, BC_RESULT_TEMP);
773 
774 #ifndef NDEBUG
775 	// This is just to ensure that the generated number is correct. I also use
776 	// braces because I declare every local at the top of the scope.
777 	{
778 		BcResult *r = bc_vec_top(&p->results);
779 		assert(BC_NUM_RDX_VALID_NP(r->d.n));
780 	}
781 #endif // NDEBUG
782 }
783 #endif // BC_ENABLE_EXTRA_MATH
784 
785 /**
786  * Prints a series of characters, without escapes.
787  * @param str  The string (series of characters).
788  */
789 static void bc_program_printChars(const char *str) {
790 
791 	const char *nl;
792 	size_t len = vm.nchars + strlen(str);
793 	sig_atomic_t lock;
794 
795 	BC_SIG_TRYLOCK(lock);
796 
797 	bc_file_puts(&vm.fout, bc_flush_save, str);
798 
799 	// We need to update the number of characters, so we find the last newline
800 	// and set the characters accordingly.
801 	nl = strrchr(str, '\n');
802 
803 	if (nl != NULL) len = strlen(nl + 1);
804 
805 	vm.nchars = len > UINT16_MAX ? UINT16_MAX : (uint16_t) len;
806 
807 	BC_SIG_TRYUNLOCK(lock);
808 }
809 
810 /**
811  * Prints a string with escapes.
812  * @param str  The string.
813  */
814 static void bc_program_printString(const char *restrict str) {
815 
816 	size_t i, len = strlen(str);
817 
818 #if DC_ENABLED
819 	// This is to ensure a nul byte is printed for dc's stream operation.
820 	if (!len && BC_IS_DC) {
821 		bc_vm_putchar('\0', bc_flush_save);
822 		return;
823 	}
824 #endif // DC_ENABLED
825 
826 	// Loop over the characters, processing escapes and printing the rest.
827 	for (i = 0; i < len; ++i) {
828 
829 		int c = str[i];
830 
831 		// If we have an escape...
832 		if (c == '\\' && i != len - 1) {
833 
834 			const char *ptr;
835 
836 			// Get the escape character and its companion.
837 			c = str[++i];
838 			ptr = strchr(bc_program_esc_chars, c);
839 
840 			// If we have a companion character...
841 			if (ptr != NULL) {
842 
843 				// We need to specially handle a newline.
844 				if (c == 'n') {
845 					BC_SIG_LOCK;
846 					vm.nchars = UINT16_MAX;
847 					BC_SIG_UNLOCK;
848 				}
849 
850 				// Grab the actual character.
851 				c = bc_program_esc_seqs[(size_t) (ptr - bc_program_esc_chars)];
852 			}
853 			else {
854 				// Just print the backslash if there is no companion character.
855 				// The following character will be printed later after the outer
856 				// if statement.
857 				bc_vm_putchar('\\', bc_flush_save);
858 			}
859 		}
860 
861 		bc_vm_putchar(c, bc_flush_save);
862 	}
863 }
864 
865 /**
866  * Executes a print. This function handles all printing except streaming.
867  * @param p     The program.
868  * @param inst  The instruction for the type of print we are doing.
869  * @param idx   The index of the result that we are printing.
870  */
871 static void bc_program_print(BcProgram *p, uchar inst, size_t idx) {
872 
873 	BcResult *r;
874 	char *str;
875 	BcNum *n;
876 	bool pop = (inst != BC_INST_PRINT);
877 
878 	assert(p != NULL);
879 
880 #ifndef BC_PROG_NO_STACK_CHECK
881 	if (BC_IS_DC) {
882 		if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 1)))
883 			bc_err(BC_ERR_EXEC_STACK);
884 	}
885 #endif // BC_PROG_NO_STACK_CHECK
886 
887 	assert(BC_PROG_STACK(&p->results, idx + 1));
888 
889 	r = bc_vec_item_rev(&p->results, idx);
890 
891 #if BC_ENABLED
892 	// If we have a void value, that's not necessarily an error. It is if pop is
893 	// true because that means that we are executing a print statement, but
894 	// attempting to do a print on a lone void value is allowed because that's
895 	// exactly how we want void values used.
896 	if (r->t == BC_RESULT_VOID) {
897 		if (BC_ERR(pop)) bc_err(BC_ERR_EXEC_VOID_VAL);
898 		bc_vec_pop(&p->results);
899 		return;
900 	}
901 #endif // BC_ENABLED
902 
903 	n = bc_program_num(p, r);
904 
905 	// If we have a number...
906 	if (BC_PROG_NUM(r, n)) {
907 
908 #if BC_ENABLED
909 		assert(inst != BC_INST_PRINT_STR);
910 #endif // BC_ENABLED
911 
912 		// Print the number.
913 		bc_num_print(n, BC_PROG_OBASE(p), !pop);
914 
915 #if BC_ENABLED
916 		// Need to store the number in last.
917 		if (BC_IS_BC) bc_num_copy(&p->last, n);
918 #endif // BC_ENABLED
919 	}
920 	else {
921 
922 		// We want to flush any stuff in the stdout buffer first.
923 		bc_file_flush(&vm.fout, bc_flush_save);
924 		str = bc_program_string(p, n);
925 
926 #if BC_ENABLED
927 		if (inst == BC_INST_PRINT_STR) bc_program_printChars(str);
928 		else
929 #endif // BC_ENABLED
930 		{
931 			bc_program_printString(str);
932 
933 			// Need to print a newline only in this case.
934 			if (inst == BC_INST_PRINT)
935 				bc_vm_putchar('\n', bc_flush_err);
936 		}
937 	}
938 
939 	// bc always pops.
940 	if (BC_IS_BC || pop) bc_vec_pop(&p->results);
941 }
942 
943 void bc_program_negate(BcResult *r, BcNum *n) {
944 	bc_num_copy(&r->d.n, n);
945 	if (BC_NUM_NONZERO(&r->d.n)) BC_NUM_NEG_TGL_NP(r->d.n);
946 }
947 
948 void bc_program_not(BcResult *r, BcNum *n) {
949 	if (!bc_num_cmpZero(n)) bc_num_one(&r->d.n);
950 }
951 
952 #if BC_ENABLE_EXTRA_MATH
953 void bc_program_trunc(BcResult *r, BcNum *n) {
954 	bc_num_copy(&r->d.n, n);
955 	bc_num_truncate(&r->d.n, n->scale);
956 }
957 #endif // BC_ENABLE_EXTRA_MATH
958 
959 /**
960  * Runs a unary operation.
961  * @param p     The program.
962  * @param inst  The unary operation.
963  */
964 static void bc_program_unary(BcProgram *p, uchar inst) {
965 
966 	BcResult *res, *ptr;
967 	BcNum *num;
968 
969 	res = bc_program_prepResult(p);
970 
971 	bc_program_prep(p, &ptr, &num, 1);
972 
973 	BC_SIG_LOCK;
974 
975 	bc_num_init(&res->d.n, num->len);
976 
977 	BC_SIG_UNLOCK;
978 
979 	// This calls a function that is in an array.
980 	bc_program_unarys[inst - BC_INST_NEG](res, num);
981 	bc_program_retire(p, 1, 1);
982 }
983 
984 /**
985  * Executes a logical operator.
986  * @param p     The program.
987  * @param inst  The operator.
988  */
989 static void bc_program_logical(BcProgram *p, uchar inst) {
990 
991 	BcResult *opd1, *opd2, *res;
992 	BcNum *n1, *n2;
993 	bool cond = 0;
994 	ssize_t cmp;
995 
996 	res = bc_program_prepResult(p);
997 
998 	// All logical operators (except boolean not, which is taken care of by
999 	// bc_program_unary()), are binary operators.
1000 	bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, 1);
1001 
1002 	// Boolean and and or are not short circuiting. This is why; they can be
1003 	// implemented much easier this way.
1004 	if (inst == BC_INST_BOOL_AND)
1005 		cond = (bc_num_cmpZero(n1) && bc_num_cmpZero(n2));
1006 	else if (inst == BC_INST_BOOL_OR)
1007 		cond = (bc_num_cmpZero(n1) || bc_num_cmpZero(n2));
1008 	else {
1009 
1010 		// We have a relational operator, so do a comparison.
1011 		cmp = bc_num_cmp(n1, n2);
1012 
1013 		switch (inst) {
1014 
1015 			case BC_INST_REL_EQ:
1016 			{
1017 				cond = (cmp == 0);
1018 				break;
1019 			}
1020 
1021 			case BC_INST_REL_LE:
1022 			{
1023 				cond = (cmp <= 0);
1024 				break;
1025 			}
1026 
1027 			case BC_INST_REL_GE:
1028 			{
1029 				cond = (cmp >= 0);
1030 				break;
1031 			}
1032 
1033 			case BC_INST_REL_NE:
1034 			{
1035 				cond = (cmp != 0);
1036 				break;
1037 			}
1038 
1039 			case BC_INST_REL_LT:
1040 			{
1041 				cond = (cmp < 0);
1042 				break;
1043 			}
1044 
1045 			case BC_INST_REL_GT:
1046 			{
1047 				cond = (cmp > 0);
1048 				break;
1049 			}
1050 #ifndef NDEBUG
1051 			default:
1052 			{
1053 				// There is a bug if we get here.
1054 				abort();
1055 			}
1056 #endif // NDEBUG
1057 		}
1058 	}
1059 
1060 	BC_SIG_LOCK;
1061 
1062 	bc_num_init(&res->d.n, BC_NUM_DEF_SIZE);
1063 
1064 	BC_SIG_UNLOCK;
1065 
1066 	if (cond) bc_num_one(&res->d.n);
1067 
1068 	bc_program_retire(p, 1, 2);
1069 }
1070 
1071 /**
1072  * Assigns a string to a variable.
1073  * @param p     The program.
1074  * @param num   The location of the string as a BcNum.
1075  * @param v     The stack for the variable.
1076  * @param push  Whether to push the string or not. To push means to move the
1077  *              string from the results stack and push it onto the variable
1078  *              stack.
1079  */
1080 static void bc_program_assignStr(BcProgram *p, BcNum *num, BcVec *v, bool push)
1081 {
1082 	BcNum *n;
1083 
1084 	assert(BC_PROG_STACK(&p->results, 1 + !push));
1085 	assert(num != NULL && num->num == NULL && num->cap == 0);
1086 
1087 	// If we are not pushing onto the variable stack, we need to replace the
1088 	// top of the variable stack.
1089 	if (!push) bc_vec_pop(v);
1090 
1091 	bc_vec_npop(&p->results, 1 + !push);
1092 
1093 	n = bc_vec_pushEmpty(v);
1094 
1095 	// We can just copy because the num should not have allocated anything.
1096 	memcpy(n, num, sizeof(BcNum));
1097 }
1098 
1099 /**
1100  * Copies a value to a variable. This is used for storing in dc as well as to
1101  * set function parameters to arguments in bc.
1102  * @param p     The program.
1103  * @param idx   The index of the variable or array to copy to.
1104  * @param t     The type to copy to. This could be a variable or an array.
1105  * @param last  Whether to grab the last item on the variable stack or not (for
1106  *              bc function parameters). This is important because if a new
1107  *              value has been pushed to the variable already, we need to grab
1108  *              the value pushed before. This happens when you have a parameter
1109  *              named something like "x", and a variable "x" is passed to
1110  *              another parameter.
1111  */
1112 static void bc_program_copyToVar(BcProgram *p, size_t idx, BcType t, bool last)
1113 {
1114 	BcResult *ptr = NULL, r;
1115 	BcVec *vec;
1116 	BcNum *n = NULL;
1117 	bool var = (t == BC_TYPE_VAR);
1118 
1119 #if DC_ENABLED
1120 	// Check the stack for dc.
1121 	if (BC_IS_DC) {
1122 		if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_err(BC_ERR_EXEC_STACK);
1123 	}
1124 #endif
1125 
1126 	assert(BC_PROG_STACK(&p->results, 1));
1127 
1128 	bc_program_operand(p, &ptr, &n, 0);
1129 
1130 #if BC_ENABLED
1131 	// Get the variable for a bc function call.
1132 	if (BC_IS_BC)
1133 	{
1134 		// Type match the result.
1135 		bc_program_type_match(ptr, t);
1136 
1137 		// Get the variable or array, taking care to get the real item. We take
1138 		// care of last with arrays later.
1139 		if (!last && var)
1140 			n = bc_vec_item_rev(bc_program_vec(p, ptr->d.loc.loc, t), 1);
1141 	}
1142 #endif // BC_ENABLED
1143 
1144 	vec = bc_program_vec(p, idx, t);
1145 
1146 	// We can shortcut in dc if it's assigning a string by using
1147 	// bc_program_assignStr().
1148 	if (ptr->t == BC_RESULT_STR) {
1149 
1150 		assert(BC_PROG_STR(n));
1151 
1152 		if (BC_ERR(!var)) bc_err(BC_ERR_EXEC_TYPE);
1153 
1154 		bc_program_assignStr(p, n, vec, true);
1155 
1156 		return;
1157 	}
1158 
1159 	BC_SIG_LOCK;
1160 
1161 	// Just create and copy for a normal variable.
1162 	if (var) {
1163 		if (BC_PROG_STR(n)) memcpy(&r.d.n, n, sizeof(BcNum));
1164 		else bc_num_createCopy(&r.d.n, n);
1165 	}
1166 	else {
1167 
1168 		// If we get here, we are handling an array. This is one place we need
1169 		// to cast the number from bc_program_num() to a vector.
1170 		BcVec *v = (BcVec*) n, *rv = &r.d.v;
1171 
1172 #if BC_ENABLED
1173 
1174 		if (BC_IS_BC) {
1175 
1176 			BcVec *parent;
1177 			bool ref, ref_size;
1178 
1179 			// We need to figure out if the parameter is a reference or not and
1180 			// construct the reference vector, if necessary. So this gets the
1181 			// parent stack for the array.
1182 			parent = bc_program_vec(p, ptr->d.loc.loc, t);
1183 			assert(parent != NULL);
1184 
1185 			// This takes care of last for arrays. Mostly.
1186 			if (!last) v = bc_vec_item_rev(parent, !last);
1187 			assert(v != NULL);
1188 
1189 			// True if we are using a reference.
1190 			ref = (v->size == sizeof(BcNum) && t == BC_TYPE_REF);
1191 
1192 			// True if we already have a reference vector. This is slightly
1193 			// (okay, a lot; it just doesn't look that way) different from
1194 			// above. The above means that we need to construct a reference
1195 			// vector, whereas this means that we have one and we might have to
1196 			// *dereference* it.
1197 			ref_size = (v->size == sizeof(uchar));
1198 
1199 			// If we *should* have a reference.
1200 			if (ref || (ref_size && t == BC_TYPE_REF)) {
1201 
1202 				// Create a new reference vector.
1203 				bc_vec_init(rv, sizeof(uchar), BC_DTOR_NONE);
1204 
1205 				// If this is true, then we need to construct a reference.
1206 				if (ref) {
1207 
1208 					assert(parent->len >= (size_t) (!last + 1));
1209 
1210 					// Make sure the pointer was not invalidated.
1211 					vec = bc_program_vec(p, idx, t);
1212 
1213 					// Push the indices onto the reference vector. This takes
1214 					// care of last; it ensures the reference goes to the right
1215 					// place.
1216 					bc_vec_pushIndex(rv, ptr->d.loc.loc);
1217 					bc_vec_pushIndex(rv, parent->len - !last - 1);
1218 				}
1219 				// If we get here, we are copying a ref to a ref. Just push a
1220 				// copy of all of the bytes.
1221 				else bc_vec_npush(rv, v->len * sizeof(uchar), v->v);
1222 
1223 				// Push the reference vector onto the array stack and pop the
1224 				// source.
1225 				bc_vec_push(vec, &r.d);
1226 				bc_vec_pop(&p->results);
1227 
1228 				// We need to return early to avoid executing code that we must
1229 				// not touch.
1230 				BC_SIG_UNLOCK;
1231 				return;
1232 			}
1233 			// If we get here, we have a reference, but we need an array, so
1234 			// dereference the array.
1235 			else if (ref_size && t != BC_TYPE_REF)
1236 				v = bc_program_dereference(p, v);
1237 		}
1238 #endif // BC_ENABLED
1239 
1240 		// If we get here, we need to copy the array because in bc, all
1241 		// arguments are passed by value. Yes, this is expensive.
1242 		bc_array_init(rv, true);
1243 		bc_array_copy(rv, v);
1244 	}
1245 
1246 	// Push the vector onto the array stack and pop the source.
1247 	bc_vec_push(vec, &r.d);
1248 	bc_vec_pop(&p->results);
1249 
1250 	BC_SIG_UNLOCK;
1251 }
1252 
1253 /**
1254  * Executes an assignment operator.
1255  * @param p     The program.
1256  * @param inst  The assignment operator to execute.
1257  */
1258 static void bc_program_assign(BcProgram *p, uchar inst) {
1259 
1260 	// The local use_val is true when the assigned value needs to be copied.
1261 	BcResult *left, *right, res;
1262 	BcNum *l, *r;
1263 	bool ob, sc, use_val = BC_INST_USE_VAL(inst);
1264 
1265 	bc_program_assignPrep(p, &left, &l, &right, &r);
1266 
1267 	// Assigning to a string should be impossible simply because of the parse.
1268 	assert(left->t != BC_RESULT_STR);
1269 
1270 	// If we are assigning a string...
1271 	if (right->t == BC_RESULT_STR) {
1272 
1273 		assert(BC_PROG_STR(r));
1274 
1275 #if BC_ENABLED
1276 		if (inst != BC_INST_ASSIGN && inst != BC_INST_ASSIGN_NO_VAL)
1277 			bc_err(BC_ERR_EXEC_TYPE);
1278 #endif // BC_ENABLED
1279 
1280 		// If we are assigning to an array element...
1281 		if (left->t == BC_RESULT_ARRAY_ELEM) {
1282 
1283 			BC_SIG_LOCK;
1284 
1285 			// We need to free the number and clear it.
1286 			bc_num_free(l);
1287 
1288 			memcpy(l, r, sizeof(BcNum));
1289 
1290 			// Now we can pop the results.
1291 			bc_vec_npop(&p->results, 2);
1292 
1293 			BC_SIG_UNLOCK;
1294 		}
1295 		else {
1296 
1297 			// If we get here, we are assigning to a variable, which we can use
1298 			// bc_program_assignStr() for.
1299 			BcVec *v = bc_program_vec(p, left->d.loc.loc, BC_TYPE_VAR);
1300 			bc_program_assignStr(p, r, v, false);
1301 		}
1302 
1303 #if BC_ENABLED
1304 
1305 		// If this is true, the value is going to be used again, so we want to
1306 		// push a temporary with the string.
1307 		if (inst == BC_INST_ASSIGN) {
1308 			res.t = BC_RESULT_STR;
1309 			memcpy(&res.d.n, r, sizeof(BcNum));
1310 			bc_vec_push(&p->results, &res);
1311 		}
1312 
1313 #endif // BC_ENABLED
1314 
1315 		// By using bc_program_assignStr(), we short-circuited this, so return.
1316 		return;
1317 	}
1318 
1319 	// If we have a normal assignment operator, not a math one...
1320 	if (BC_INST_IS_ASSIGN(inst)) {
1321 
1322 		// Assigning to a variable that has a string here is fine because there
1323 		// is no math done on it.
1324 
1325 		// BC_RESULT_TEMP, BC_RESULT_IBASE, BC_RESULT_OBASE, BC_RESULT_SCALE,
1326 		// and BC_RESULT_SEED all have temporary copies. Because that's the
1327 		// case, we can free the left and just move the value over. We set the
1328 		// type of right to BC_RESULT_ZERO in order to prevent it from being
1329 		// freed. We also don't have to worry about BC_RESULT_STR because it's
1330 		// take care of above.
1331 		if (right->t == BC_RESULT_TEMP || right->t >= BC_RESULT_IBASE) {
1332 
1333 			BC_SIG_LOCK;
1334 
1335 			bc_num_free(l);
1336 			memcpy(l, r, sizeof(BcNum));
1337 			right->t = BC_RESULT_ZERO;
1338 
1339 			BC_SIG_UNLOCK;
1340 		}
1341 		// Copy over.
1342 		else bc_num_copy(l, r);
1343 	}
1344 #if BC_ENABLED
1345 	else {
1346 
1347 		// If we get here, we are doing a math assignment (+=, -=, etc.). So
1348 		// we need to prepare for a binary operator.
1349 		BcBigDig scale = BC_PROG_SCALE(p);
1350 
1351 		// At this point, the left side could still be a string because it could
1352 		// be a variable that has the string. If that's the case, we have a type
1353 		// error.
1354 		if (BC_PROG_STR(l)) bc_err(BC_ERR_EXEC_TYPE);
1355 
1356 		// Get the right type of assignment operator, whether val is used or
1357 		// NO_VAL for performance.
1358 		if (!use_val)
1359 			inst -= (BC_INST_ASSIGN_POWER_NO_VAL - BC_INST_ASSIGN_POWER);
1360 
1361 		assert(BC_NUM_RDX_VALID(l));
1362 		assert(BC_NUM_RDX_VALID(r));
1363 
1364 		// Run the actual operation. We do not need worry about reallocating l
1365 		// because bc_num_binary() does that behind the scenes for us.
1366 		bc_program_ops[inst - BC_INST_ASSIGN_POWER](l, r, l, scale);
1367 	}
1368 #endif // BC_ENABLED
1369 
1370 	ob = (left->t == BC_RESULT_OBASE);
1371 	sc = (left->t == BC_RESULT_SCALE);
1372 
1373 	// The globals need special handling, especially the non-seed ones. The
1374 	// first part of the if statement handles them.
1375 	if (ob || sc || left->t == BC_RESULT_IBASE) {
1376 
1377 		BcVec *v;
1378 		BcBigDig *ptr, *ptr_t, val, max, min;
1379 
1380 		// Get the actual value.
1381 		val = bc_num_bigdig(l);
1382 
1383 		// Scale needs handling separate from ibase and obase.
1384 		if (sc) {
1385 
1386 			// Set the min and max.
1387 			min = 0;
1388 			max = vm.maxes[BC_PROG_GLOBALS_SCALE];
1389 
1390 			// Get a pointer to the stack and to the current value.
1391 			v = p->globals_v + BC_PROG_GLOBALS_SCALE;
1392 			ptr_t = p->globals + BC_PROG_GLOBALS_SCALE;
1393 		}
1394 		else {
1395 
1396 			// Set the min and max.
1397 			min = BC_NUM_MIN_BASE;
1398 			if (BC_ENABLE_EXTRA_MATH && ob && (BC_IS_DC || !BC_IS_POSIX))
1399 				min = 0;
1400 			max = vm.maxes[ob + BC_PROG_GLOBALS_IBASE];
1401 
1402 			// Get a pointer to the stack and to the current value.
1403 			v = p->globals_v + BC_PROG_GLOBALS_IBASE + ob;
1404 			ptr_t = p->globals + BC_PROG_GLOBALS_IBASE + ob;
1405 		}
1406 
1407 		// Check for error.
1408 		if (BC_ERR(val > max || val < min)) {
1409 
1410 			// This grabs the right error.
1411 			BcErr e = left->t - BC_RESULT_IBASE + BC_ERR_EXEC_IBASE;
1412 
1413 			bc_verr(e, min, max);
1414 		}
1415 
1416 		// Set the top of the stack and the actual global value.
1417 		ptr = bc_vec_top(v);
1418 		*ptr = val;
1419 		*ptr_t = val;
1420 	}
1421 #if BC_ENABLE_EXTRA_MATH
1422 	// To assign to steed, let bc_num_rng() do its magic.
1423 	else if (left->t == BC_RESULT_SEED) bc_num_rng(l, &p->rng);
1424 #endif // BC_ENABLE_EXTRA_MATH
1425 
1426 	BC_SIG_LOCK;
1427 
1428 	// If we needed to use the value, then we need to copy it. Otherwise, we can
1429 	// pop indiscriminately. Oh, and the copy should be a BC_RESULT_TEMP.
1430 	if (use_val) {
1431 		bc_num_createCopy(&res.d.n, l);
1432 		res.t = BC_RESULT_TEMP;
1433 		bc_vec_npop(&p->results, 2);
1434 		bc_vec_push(&p->results, &res);
1435 	}
1436 	else bc_vec_npop(&p->results, 2);
1437 
1438 	BC_SIG_UNLOCK;
1439 }
1440 
1441 /**
1442  * Pushes a variable's value onto the results stack.
1443  * @param p     The program.
1444  * @param code  The bytecode vector to pull the variable's index out of.
1445  * @param bgn   An in/out parameter; the start of the index in the bytecode
1446  *              vector, and will be updated to point after the index on return.
1447  * @param pop   True if the variable's value should be popped off its stack.
1448  *              This is only used in dc.
1449  * @param copy  True if the variable's value should be copied to the results
1450  *              stack. This is only used in dc.
1451  */
1452 static void bc_program_pushVar(BcProgram *p, const char *restrict code,
1453                                size_t *restrict bgn, bool pop, bool copy)
1454 {
1455 	BcResult r;
1456 	size_t idx = bc_program_index(code, bgn);
1457 
1458 	// Set the result appropriately.
1459 	r.t = BC_RESULT_VAR;
1460 	r.d.loc.loc = idx;
1461 
1462 #if DC_ENABLED
1463 	// If this condition is true, then we have the hard case, where we have to
1464 	// adjust dc registers.
1465 	if (BC_IS_DC && (pop || copy)) {
1466 
1467 		// Get the stack for the variable and the number at the top.
1468 		BcVec *v = bc_program_vec(p, idx, BC_TYPE_VAR);
1469 		BcNum *num = bc_vec_top(v);
1470 
1471 		// Ensure there are enough elements on the stack.
1472 		if (BC_ERR(!BC_PROG_STACK(v, 2 - copy))) {
1473 			const char *name = bc_map_name(&p->var_map, idx);
1474 			bc_verr(BC_ERR_EXEC_STACK_REGISTER, name);
1475 		}
1476 
1477 		assert(BC_PROG_STACK(v, 2 - copy));
1478 
1479 		// If the top of the stack is actually a number...
1480 		if (!BC_PROG_STR(num)) {
1481 
1482 			BC_SIG_LOCK;
1483 
1484 			// Create a copy to go onto the results stack as appropriate.
1485 			r.t = BC_RESULT_TEMP;
1486 			bc_num_createCopy(&r.d.n, num);
1487 
1488 			// If we are not actually copying, we need to do a replace, so pop.
1489 			if (!copy) bc_vec_pop(v);
1490 
1491 			bc_vec_push(&p->results, &r);
1492 
1493 			BC_SIG_UNLOCK;
1494 
1495 			return;
1496 		}
1497 		else {
1498 			// Set the string result. We can just memcpy because all of the
1499 			// fields in the num should be cleared.
1500 			memcpy(&r.d.n, num, sizeof(BcNum));
1501 			r.t = BC_RESULT_STR;
1502 		}
1503 
1504 		// If we are not actually copying, we need to do a replace, so pop.
1505 		if (!copy) bc_vec_pop(v);
1506 	}
1507 #endif // DC_ENABLED
1508 
1509 	bc_vec_push(&p->results, &r);
1510 }
1511 
1512 /**
1513  * Pushes an array or an array element onto the results stack.
1514  * @param p     The program.
1515  * @param code  The bytecode vector to pull the variable's index out of.
1516  * @param bgn   An in/out parameter; the start of the index in the bytecode
1517  *              vector, and will be updated to point after the index on return.
1518  * @param inst  The instruction; whether to push an array or an array element.
1519  */
1520 static void bc_program_pushArray(BcProgram *p, const char *restrict code,
1521                                  size_t *restrict bgn, uchar inst)
1522 {
1523 	BcResult r, *operand;
1524 	BcNum *num;
1525 	BcBigDig temp;
1526 
1527 	// Get the index of the array.
1528 	r.d.loc.loc = bc_program_index(code, bgn);
1529 
1530 	// Doing an array is easy; just set the result type and finish.
1531 	if (inst == BC_INST_ARRAY) {
1532 		r.t = BC_RESULT_ARRAY;
1533 		bc_vec_push(&p->results, &r);
1534 		return;
1535 	}
1536 
1537 	// Grab the top element of the results stack for the array index.
1538 	bc_program_prep(p, &operand, &num, 0);
1539 	temp = bc_num_bigdig(num);
1540 
1541 	// Set the result.
1542 	r.t = BC_RESULT_ARRAY_ELEM;
1543 	r.d.loc.idx = (size_t) temp;
1544 
1545 	BC_SIG_LOCK;
1546 
1547 	// Pop the index and push the element.
1548 	bc_vec_pop(&p->results);
1549 	bc_vec_push(&p->results, &r);
1550 
1551 	BC_SIG_UNLOCK;
1552 }
1553 
1554 #if BC_ENABLED
1555 
1556 /**
1557  * Executes an increment or decrement operator. This only handles postfix
1558  * inc/dec because the parser translates prefix inc/dec into an assignment where
1559  * the value is used.
1560  * @param p     The program.
1561  * @param inst  The instruction; whether to do an increment or decrement.
1562  */
1563 static void bc_program_incdec(BcProgram *p, uchar inst) {
1564 
1565 	BcResult *ptr, res, copy;
1566 	BcNum *num;
1567 	uchar inst2;
1568 
1569 	bc_program_prep(p, &ptr, &num, 0);
1570 
1571 	BC_SIG_LOCK;
1572 
1573 	// We need a copy from *before* the operation.
1574 	copy.t = BC_RESULT_TEMP;
1575 	bc_num_createCopy(&copy.d.n, num);
1576 
1577 	BC_SETJMP_LOCKED(exit);
1578 
1579 	BC_SIG_UNLOCK;
1580 
1581 	// Create the proper assignment.
1582 	res.t = BC_RESULT_ONE;
1583 	inst2 = BC_INST_ASSIGN_PLUS_NO_VAL + (inst & 0x01);
1584 
1585 	bc_vec_push(&p->results, &res);
1586 	bc_program_assign(p, inst2);
1587 
1588 	BC_SIG_LOCK;
1589 
1590 	bc_vec_push(&p->results, &copy);
1591 
1592 	BC_UNSETJMP;
1593 
1594 	BC_SIG_UNLOCK;
1595 
1596 	// No need to free the copy here because we pushed it onto the stack.
1597 	return;
1598 
1599 exit:
1600 	BC_SIG_MAYLOCK;
1601 	bc_num_free(&copy.d.n);
1602 	BC_LONGJMP_CONT;
1603 }
1604 
1605 /**
1606  * Executes a function call for bc.
1607  * @param p     The program.
1608  * @param code  The bytecode vector to pull the number of arguments and the
1609  *              function index out of.
1610  * @param bgn   An in/out parameter; the start of the indices in the bytecode
1611  *              vector, and will be updated to point after the indices on
1612  *              return.
1613  */
1614 static void bc_program_call(BcProgram *p, const char *restrict code,
1615                             size_t *restrict bgn)
1616 {
1617 	BcInstPtr ip;
1618 	size_t i, nargs;
1619 	BcFunc *f;
1620 	BcVec *v;
1621 	BcAuto *a;
1622 	BcResult *arg;
1623 
1624 	// Pull the number of arguments out of the bytecode vector.
1625 	nargs = bc_program_index(code, bgn);
1626 
1627 	// Set up instruction pointer.
1628 	ip.idx = 0;
1629 	ip.func = bc_program_index(code, bgn);
1630 	f = bc_vec_item(&p->fns, ip.func);
1631 
1632 	// Error checking.
1633 	if (BC_ERR(!f->code.len)) bc_verr(BC_ERR_EXEC_UNDEF_FUNC, f->name);
1634 	if (BC_ERR(nargs != f->nparams))
1635 		bc_verr(BC_ERR_EXEC_PARAMS, f->nparams, nargs);
1636 
1637 	// Set the length of the results stack. We discount the argument, of course.
1638 	ip.len = p->results.len - nargs;
1639 
1640 	assert(BC_PROG_STACK(&p->results, nargs));
1641 
1642 	// Prepare the globals' stacks.
1643 	if (BC_G) bc_program_prepGlobals(p);
1644 
1645 	// Push the arguments onto the stacks of their respective parameters.
1646 	for (i = 0; i < nargs; ++i) {
1647 
1648 		size_t j;
1649 		bool last = true;
1650 
1651 		arg = bc_vec_top(&p->results);
1652 		if (BC_ERR(arg->t == BC_RESULT_VOID)) bc_err(BC_ERR_EXEC_VOID_VAL);
1653 
1654 		// Get the corresponding parameter.
1655 		a = bc_vec_item(&f->autos, nargs - 1 - i);
1656 
1657 		// If I have already pushed to a var, I need to make sure I
1658 		// get the previous version, not the already pushed one. This condition
1659 		// must be true for that to even be possible.
1660 		if (arg->t == BC_RESULT_VAR || arg->t == BC_RESULT_ARRAY) {
1661 
1662 			// Loop through all of the previous parameters.
1663 			for (j = 0; j < i && last; ++j) {
1664 
1665 				BcAuto *aptr = bc_vec_item(&f->autos, nargs - 1 - j);
1666 
1667 				// This condition is true if there is a previous parameter with
1668 				// the same name *and* type because variables and arrays do not
1669 				// interfere with each other.
1670 				last = (arg->d.loc.loc != aptr->idx ||
1671 				        (!aptr->type) != (arg->t == BC_RESULT_VAR));
1672 			}
1673 		}
1674 
1675 		// Actually push the value onto the parameter's stack.
1676 		bc_program_copyToVar(p, a->idx, a->type, last);
1677 	}
1678 
1679 	BC_SIG_LOCK;
1680 
1681 	// Push zeroes onto the stacks of the auto variables.
1682 	for (; i < f->autos.len; ++i) {
1683 
1684 		// Get the auto and its stack.
1685 		a = bc_vec_item(&f->autos, i);
1686 		v = bc_program_vec(p, a->idx, a->type);
1687 
1688 		// If a variable, just push a 0; otherwise, push an array.
1689 		if (a->type == BC_TYPE_VAR) {
1690 			BcNum *n = bc_vec_pushEmpty(v);
1691 			bc_num_init(n, BC_NUM_DEF_SIZE);
1692 		}
1693 		else {
1694 
1695 			BcVec *v2;
1696 
1697 			assert(a->type == BC_TYPE_ARRAY);
1698 
1699 			v2 = bc_vec_pushEmpty(v);
1700 			bc_array_init(v2, true);
1701 		}
1702 	}
1703 
1704 	// Push the instruction pointer onto the execution stack.
1705 	bc_vec_push(&p->stack, &ip);
1706 
1707 	BC_SIG_UNLOCK;
1708 }
1709 
1710 /**
1711  * Executes a return instruction.
1712  * @param p     The program.
1713  * @param inst  The return instruction. bc can return void, and we need to know
1714  *              if it is.
1715  */
1716 static void bc_program_return(BcProgram *p, uchar inst) {
1717 
1718 	BcResult *res;
1719 	BcFunc *f;
1720 	BcInstPtr *ip;
1721 	size_t i, nresults;
1722 
1723 	// Get the instruction pointer.
1724 	ip = bc_vec_top(&p->stack);
1725 
1726 	// Get the difference between the actual number of results and the number of
1727 	// results the caller expects.
1728 	nresults = p->results.len - ip->len;
1729 
1730 	// If this isn't true, there was a missing call somewhere.
1731 	assert(BC_PROG_STACK(&p->stack, 2));
1732 
1733 	// If this isn't true, the parser screwed by giving us no value when we
1734 	// expected one, or giving us a value when we expected none.
1735 	assert(BC_PROG_STACK(&p->results, ip->len + (inst == BC_INST_RET)));
1736 
1737 	// Get the function we are returning from.
1738 	f = bc_vec_item(&p->fns, ip->func);
1739 
1740 	res = bc_program_prepResult(p);
1741 
1742 	// If we are returning normally...
1743 	if (inst == BC_INST_RET) {
1744 
1745 		BcNum *num;
1746 		BcResult *operand;
1747 
1748 		// Prepare and copy the return value.
1749 		bc_program_operand(p, &operand, &num, 1);
1750 
1751 		if (BC_PROG_STR(num)) {
1752 
1753 			// We need to set this because otherwise, it will be a
1754 			// BC_RESULT_TEMP, and BC_RESULT_TEMP needs an actual number to make
1755 			// it easier to do type checking.
1756 			res->t = BC_RESULT_STR;
1757 
1758 			memcpy(&res->d.n, num, sizeof(BcNum));
1759 		}
1760 		else {
1761 
1762 			BC_SIG_LOCK;
1763 
1764 			bc_num_createCopy(&res->d.n, num);
1765 		}
1766 	}
1767 	// Void is easy; set the result.
1768 	else if (inst == BC_INST_RET_VOID) res->t = BC_RESULT_VOID;
1769 	else {
1770 
1771 		BC_SIG_LOCK;
1772 
1773 		// If we get here, the instruction is for returning a zero, so do that.
1774 		bc_num_init(&res->d.n, BC_NUM_DEF_SIZE);
1775 	}
1776 
1777 	BC_SIG_MAYUNLOCK;
1778 
1779 	// We need to pop items off of the stacks of arguments and autos as well.
1780 	for (i = 0; i < f->autos.len; ++i) {
1781 
1782 		BcAuto *a = bc_vec_item(&f->autos, i);
1783 		BcVec *v = bc_program_vec(p, a->idx, a->type);
1784 
1785 		bc_vec_pop(v);
1786 	}
1787 
1788 	BC_SIG_LOCK;
1789 
1790 	// When we retire, pop all of the unused results.
1791 	bc_program_retire(p, 1, nresults);
1792 
1793 	// Pop the globals, if necessary.
1794 	if (BC_G) bc_program_popGlobals(p, false);
1795 
1796 	// Pop the stack. This is what causes the function to actually "return."
1797 	bc_vec_pop(&p->stack);
1798 
1799 	BC_SIG_UNLOCK;
1800 }
1801 #endif // BC_ENABLED
1802 
1803 /**
1804  * Executes a builtin function.
1805  * @param p     The program.
1806  * @param inst  The builtin to execute.
1807  */
1808 static void bc_program_builtin(BcProgram *p, uchar inst) {
1809 
1810 	BcResult *opd, *res;
1811 	BcNum *num;
1812 	bool len = (inst == BC_INST_LENGTH);
1813 
1814 	// Ensure we have a valid builtin.
1815 #if BC_ENABLE_EXTRA_MATH
1816 	assert(inst >= BC_INST_LENGTH && inst <= BC_INST_IRAND);
1817 #else // BC_ENABLE_EXTRA_MATH
1818 	assert(inst >= BC_INST_LENGTH && inst <= BC_INST_ABS);
1819 #endif // BC_ENABLE_EXTRA_MATH
1820 
1821 #ifndef BC_PROG_NO_STACK_CHECK
1822 	// Check stack for dc.
1823 	if (BC_IS_DC && BC_ERR(!BC_PROG_STACK(&p->results, 1)))
1824 		bc_err(BC_ERR_EXEC_STACK);
1825 #endif // BC_PROG_NO_STACK_CHECK
1826 
1827 	assert(BC_PROG_STACK(&p->results, 1));
1828 
1829 	res = bc_program_prepResult(p);
1830 
1831 	bc_program_operand(p, &opd, &num, 1);
1832 
1833 	assert(num != NULL);
1834 
1835 	// We need to ensure that strings and arrays aren't passed to most builtins.
1836 	// The scale function can take strings in dc.
1837 	if (!len && (inst != BC_INST_SCALE_FUNC || BC_IS_BC))
1838 		bc_program_type_num(opd, num);
1839 
1840 	// Square root is easy.
1841 	if (inst == BC_INST_SQRT) bc_num_sqrt(num, &res->d.n, BC_PROG_SCALE(p));
1842 
1843 	// Absolute value is easy.
1844 	else if (inst == BC_INST_ABS) {
1845 
1846 		BC_SIG_LOCK;
1847 
1848 		bc_num_createCopy(&res->d.n, num);
1849 
1850 		BC_SIG_UNLOCK;
1851 
1852 		BC_NUM_NEG_CLR_NP(res->d.n);
1853 	}
1854 #if BC_ENABLE_EXTRA_MATH
1855 	// irand() is easy.
1856 	else if (inst == BC_INST_IRAND) {
1857 
1858 		BC_SIG_LOCK;
1859 
1860 		bc_num_init(&res->d.n, num->len - BC_NUM_RDX_VAL(num));
1861 
1862 		BC_SIG_UNLOCK;
1863 
1864 		bc_num_irand(num, &res->d.n, &p->rng);
1865 	}
1866 #endif // BC_ENABLE_EXTRA_MATH
1867 
1868 	// Everything else is...not easy.
1869 	else {
1870 
1871 		BcBigDig val = 0;
1872 
1873 		// Well, scale() is easy, but length() is not.
1874 		if (len) {
1875 
1876 			// If we are bc and we have an array...
1877 			if (opd->t == BC_RESULT_ARRAY) {
1878 
1879 				// Yes, this is one place where we need to cast the number from
1880 				// bc_program_num() to a vector.
1881 				BcVec *v = (BcVec*) num;
1882 
1883 #if BC_ENABLED
1884 				// Dereference the array, if necessary.
1885 				if (BC_IS_BC && v->size == sizeof(uchar))
1886 					v = bc_program_dereference(p, v);
1887 #endif // BC_ENABLED
1888 
1889 				assert(v->size == sizeof(BcNum));
1890 
1891 				val = (BcBigDig) v->len;
1892 			}
1893 			else {
1894 
1895 				// If the item is a string...
1896 				if (!BC_PROG_NUM(opd, num)) {
1897 
1898 					char *str;
1899 
1900 					// Get the string, then get the length.
1901 					str = bc_program_string(p, num);
1902 					val = (BcBigDig) strlen(str);
1903 				}
1904 				else
1905 				{
1906 					// Calculate the length of the number.
1907 					val = (BcBigDig) bc_num_len(num);
1908 				}
1909 			}
1910 		}
1911 		// Like I said; scale() is actually easy. It just also needs the integer
1912 		// conversion that length() does.
1913 		else if (BC_IS_BC || BC_PROG_NUM(opd, num))
1914 			val = (BcBigDig) bc_num_scale(num);
1915 
1916 		BC_SIG_LOCK;
1917 
1918 		// Create the result.
1919 		bc_num_createFromBigdig(&res->d.n, val);
1920 
1921 		BC_SIG_UNLOCK;
1922 	}
1923 
1924 	bc_program_retire(p, 1, 1);
1925 }
1926 
1927 /**
1928  * Executes a divmod.
1929  * @param p  The program.
1930  */
1931 static void bc_program_divmod(BcProgram *p) {
1932 
1933 	BcResult *opd1, *opd2, *res, *res2;
1934 	BcNum *n1, *n2;
1935 	size_t req;
1936 
1937 	// We grow first to avoid pointer invalidation.
1938 	bc_vec_grow(&p->results, 2);
1939 
1940 	// We don't need to update the pointer because
1941 	// the capacity is enough due to the line above.
1942 	res2 = bc_program_prepResult(p);
1943 	res = bc_program_prepResult(p);
1944 
1945 	// Prepare the operands.
1946 	bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, 2);
1947 
1948 	req = bc_num_mulReq(n1, n2, BC_PROG_SCALE(p));
1949 
1950 	BC_SIG_LOCK;
1951 
1952 	// Initialize the results.
1953 	bc_num_init(&res->d.n, req);
1954 	bc_num_init(&res2->d.n, req);
1955 
1956 	BC_SIG_UNLOCK;
1957 
1958 	// Execute.
1959 	bc_num_divmod(n1, n2, &res2->d.n, &res->d.n, BC_PROG_SCALE(p));
1960 
1961 	bc_program_retire(p, 2, 2);
1962 }
1963 
1964 /**
1965  * Executes modular exponentiation.
1966  * @param p  The program.
1967  */
1968 static void bc_program_modexp(BcProgram *p) {
1969 
1970 	BcResult *r1, *r2, *r3, *res;
1971 	BcNum *n1, *n2, *n3;
1972 
1973 #if DC_ENABLED
1974 
1975 	// Check the stack.
1976 	if (BC_IS_DC && BC_ERR(!BC_PROG_STACK(&p->results, 3)))
1977 		bc_err(BC_ERR_EXEC_STACK);
1978 
1979 #endif // DC_ENABLED
1980 
1981 	assert(BC_PROG_STACK(&p->results, 3));
1982 
1983 	res = bc_program_prepResult(p);
1984 
1985 	// Get the first operand and typecheck.
1986 	bc_program_operand(p, &r1, &n1, 3);
1987 	bc_program_type_num(r1, n1);
1988 
1989 	// Get the last two operands.
1990 	bc_program_binOpPrep(p, &r2, &n2, &r3, &n3, 1);
1991 
1992 	// Make sure that the values have their pointers updated, if necessary.
1993 	// Only array elements are possible because this is dc.
1994 	if (r1->t == BC_RESULT_ARRAY_ELEM && (r1->t == r2->t || r1->t == r3->t))
1995 		n1 = bc_program_num(p, r1);
1996 
1997 	BC_SIG_LOCK;
1998 
1999 	bc_num_init(&res->d.n, n3->len);
2000 
2001 	BC_SIG_UNLOCK;
2002 
2003 	bc_num_modexp(n1, n2, n3, &res->d.n);
2004 
2005 	bc_program_retire(p, 1, 3);
2006 }
2007 
2008 /**
2009  * Asciifies a number for dc. This is a helper for bc_program_asciify().
2010  * @param p  The program.
2011  * @param n  The number to asciify.
2012  */
2013 static uchar bc_program_asciifyNum(BcProgram *p, BcNum *n) {
2014 
2015 	BcNum num;
2016 	BcBigDig val;
2017 
2018 #ifndef NDEBUG
2019 	// This is entirely to satisfy a useless scan-build error.
2020 	val = 0;
2021 #endif // NDEBUG
2022 
2023 	bc_num_clear(&num);
2024 
2025 	BC_SETJMP(num_err);
2026 
2027 	BC_SIG_LOCK;
2028 
2029 	bc_num_createCopy(&num, n);
2030 
2031 	BC_SIG_UNLOCK;
2032 
2033 	// We want to clear the scale and sign for easy mod later.
2034 	bc_num_truncate(&num, num.scale);
2035 	BC_NUM_NEG_CLR_NP(num);
2036 
2037 	// This is guaranteed to not have a divide by 0
2038 	// because strmb is equal to 256.
2039 	bc_num_mod(&num, &p->strmb, &num, 0);
2040 
2041 	// This is also guaranteed to not error because num is in the range
2042 	// [0, UCHAR_MAX], which is definitely in range for a BcBigDig. And
2043 	// it is not negative.
2044 	val = bc_num_bigdig2(&num);
2045 
2046 num_err:
2047 	BC_SIG_MAYLOCK;
2048 	bc_num_free(&num);
2049 	BC_LONGJMP_CONT;
2050 	return (uchar) val;
2051 }
2052 
2053 /**
2054  * Executes the "asciify" command in dc.
2055  * @param p     The program.
2056  * @param fidx  The index of the current function.
2057  */
2058 static void bc_program_asciify(BcProgram *p, size_t fidx) {
2059 
2060 	BcResult *r, res;
2061 	BcNum *n;
2062 	char str[2], *str2;
2063 	uchar c;
2064 	size_t idx;
2065 
2066 	// Check the stack.
2067 	if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_err(BC_ERR_EXEC_STACK);
2068 
2069 	assert(BC_PROG_STACK(&p->results, 1));
2070 
2071 	// Get the top of the results stack.
2072 	bc_program_operand(p, &r, &n, 0);
2073 
2074 	assert(n != NULL);
2075 
2076 	// Asciify.
2077 	if (BC_PROG_NUM(r, n)) c = bc_program_asciifyNum(p, n);
2078 	else {
2079 
2080 		// Get the string itself, then the first character.
2081 		str2 = bc_program_string(p, n);
2082 		c = (uchar) str2[0];
2083 	}
2084 
2085 	// Fill the resulting string.
2086 	str[0] = (char) c;
2087 	str[1] = '\0';
2088 
2089 	// Add the string to the data structures.
2090 	BC_SIG_LOCK;
2091 	idx = bc_program_addString(p, str, fidx);
2092 	BC_SIG_UNLOCK;
2093 
2094 	// Set the result
2095 	res.t = BC_RESULT_STR;
2096 	bc_num_clear(&res.d.n);
2097 	res.d.n.rdx = fidx;
2098 	res.d.n.scale = idx;
2099 
2100 	// Pop and push.
2101 	bc_vec_pop(&p->results);
2102 	bc_vec_push(&p->results, &res);
2103 }
2104 
2105 /**
2106  * Streams a number or a string to stdout.
2107  * @param p  The program.
2108  */
2109 static void bc_program_printStream(BcProgram *p) {
2110 
2111 	BcResult *r;
2112 	BcNum *n;
2113 
2114 	// Check the stack.
2115 	if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_err(BC_ERR_EXEC_STACK);
2116 
2117 	assert(BC_PROG_STACK(&p->results, 1));
2118 
2119 	// Get the top of the results stack.
2120 	bc_program_operand(p, &r, &n, 0);
2121 
2122 	assert(n != NULL);
2123 
2124 	// Stream appropriately.
2125 	if (BC_PROG_NUM(r, n)) bc_num_stream(n);
2126 	else bc_program_printChars(bc_program_string(p, n));
2127 
2128 	// Pop the operand.
2129 	bc_vec_pop(&p->results);
2130 }
2131 
2132 #if DC_ENABLED
2133 
2134 /**
2135  * Gets the length of a register in dc and pushes it onto the results stack.
2136  * @param p     The program.
2137  * @param code  The bytecode vector to pull the register's index out of.
2138  * @param bgn   An in/out parameter; the start of the index in the bytecode
2139  *              vector, and will be updated to point after the index on return.
2140  */
2141 static void bc_program_regStackLen(BcProgram *p, const char *restrict code,
2142                                    size_t *restrict bgn)
2143 {
2144 	size_t idx = bc_program_index(code, bgn);
2145 	BcVec *v = bc_program_vec(p, idx, BC_TYPE_VAR);
2146 
2147 	bc_program_pushBigdig(p, (BcBigDig) v->len, BC_RESULT_TEMP);
2148 }
2149 
2150 /**
2151  * Pushes the length of the results stack onto the results stack.
2152  * @param p  The program.
2153  */
2154 static void bc_program_stackLen(BcProgram *p) {
2155 	bc_program_pushBigdig(p, (BcBigDig) p->results.len, BC_RESULT_TEMP);
2156 }
2157 
2158 /**
2159  * Pops a certain number of elements off the execution stack.
2160  * @param p     The program.
2161  * @param inst  The instruction to tell us how many. There is one to pop up to
2162  *              2, and one to pop the amount equal to the number at the top of
2163  *              the results stack.
2164  */
2165 static void bc_program_nquit(BcProgram *p, uchar inst) {
2166 
2167 	BcResult *opnd;
2168 	BcNum *num;
2169 	BcBigDig val;
2170 	size_t i;
2171 
2172 	// Ensure that the tail calls stack is correct.
2173 	assert(p->stack.len == p->tail_calls.len);
2174 
2175 	// Get the number of executions to pop.
2176 	if (inst == BC_INST_QUIT) val = 2;
2177 	else {
2178 
2179 		bc_program_prep(p, &opnd, &num, 0);
2180 		val = bc_num_bigdig(num);
2181 
2182 		bc_vec_pop(&p->results);
2183 	}
2184 
2185 	// Loop over the tail call stack and adjust the quit value appropriately.
2186 	for (i = 0; val && i < p->tail_calls.len; ++i) {
2187 
2188 		// Get the number of tail calls for this one.
2189 		size_t calls = *((size_t*) bc_vec_item_rev(&p->tail_calls, i)) + 1;
2190 
2191 		// Adjust the value.
2192 		if (calls >= val) val = 0;
2193 		else val -= (BcBigDig) calls;
2194 	}
2195 
2196 	// If we don't have enough executions, just quit.
2197 	if (i == p->stack.len) {
2198 		vm.status = BC_STATUS_QUIT;
2199 		BC_JMP;
2200 	}
2201 	else {
2202 		// We can always pop the last item we reached on the tail call stack
2203 		// because these are for tail calls. That means that any executions that
2204 		// we would not have quit in that position on the stack would have quit
2205 		// anyway.
2206 		BC_SIG_LOCK;
2207 		bc_vec_npop(&p->stack, i);
2208 		bc_vec_npop(&p->tail_calls, i);
2209 		BC_SIG_UNLOCK;
2210 	}
2211 }
2212 
2213 /**
2214  * Pushes the depth of the execution stack onto the stack.
2215  * @param p  The program.
2216  */
2217 static void bc_program_execStackLen(BcProgram *p) {
2218 
2219 	size_t i, amt, len = p->tail_calls.len;
2220 
2221 	amt = len;
2222 
2223 	for (i = 0; i < len; ++i)
2224 		amt += *((size_t*) bc_vec_item(&p->tail_calls, i));
2225 
2226 	bc_program_pushBigdig(p, (BcBigDig) amt, BC_RESULT_TEMP);
2227 }
2228 
2229 /**
2230  *
2231  * @param p     The program.
2232  * @param code  The bytecode vector to pull the register's index out of.
2233  * @param bgn   An in/out parameter; the start of the index in the bytecode
2234  *              vector, and will be updated to point after the index on return.
2235  * @param cond  True if the execution is conditional, false otherwise.
2236  * @param len   The number of bytes in the bytecode vector.
2237  */
2238 static void bc_program_execStr(BcProgram *p, const char *restrict code,
2239                                size_t *restrict bgn, bool cond, size_t len)
2240 {
2241 	BcResult *r;
2242 	char *str;
2243 	BcFunc *f;
2244 	BcInstPtr ip;
2245 	size_t fidx;
2246 	BcNum *n;
2247 
2248 	assert(p->stack.len == p->tail_calls.len);
2249 
2250 	// Check the stack.
2251 	if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_err(BC_ERR_EXEC_STACK);
2252 
2253 	assert(BC_PROG_STACK(&p->results, 1));
2254 
2255 	// Get the operand.
2256 	bc_program_operand(p, &r, &n, 0);
2257 
2258 	// If execution is conditional...
2259 	if (cond) {
2260 
2261 		bool exec;
2262 		size_t idx, then_idx, else_idx;
2263 
2264 		// Get the index of the "then" var and "else" var.
2265 		then_idx = bc_program_index(code, bgn);
2266 		else_idx = bc_program_index(code, bgn);
2267 
2268 		// Figure out if we should execute.
2269 		exec = (r->d.n.len != 0);
2270 
2271 		idx = exec ? then_idx : else_idx;
2272 
2273 		BC_SIG_LOCK;
2274 		BC_SETJMP_LOCKED(exit);
2275 
2276 		// If we are supposed to execute, execute. If else_idx == SIZE_MAX, that
2277 		// means there was no else clause, so if execute is false and else does
2278 		// not exist, we don't execute. The goto skips all of the setup for the
2279 		// execution.
2280 		if (exec || (else_idx != SIZE_MAX))
2281 			n = bc_vec_top(bc_program_vec(p, idx, BC_TYPE_VAR));
2282 		else goto exit;
2283 
2284 		if (BC_ERR(!BC_PROG_STR(n))) bc_err(BC_ERR_EXEC_TYPE);
2285 
2286 		BC_UNSETJMP;
2287 		BC_SIG_UNLOCK;
2288 	}
2289 	else {
2290 
2291 		// In non-conditional situations, only the top of stack can be executed,
2292 		// and in those cases, variables are not allowed to be "on the stack";
2293 		// they are only put on the stack to be assigned to.
2294 		assert(r->t != BC_RESULT_VAR);
2295 
2296 		if (r->t != BC_RESULT_STR) return;
2297 	}
2298 
2299 	assert(BC_PROG_STR(n));
2300 
2301 	// Get the string.
2302 	str = bc_program_string(p, n);
2303 
2304 	// Get the function index and function.
2305 	BC_SIG_LOCK;
2306 	fidx = bc_program_insertFunc(p, str);
2307 	BC_SIG_UNLOCK;
2308 	f = bc_vec_item(&p->fns, fidx);
2309 
2310 	// If the function has not been parsed yet...
2311 	if (!f->code.len) {
2312 
2313 		BC_SIG_LOCK;
2314 
2315 		if (!BC_PARSE_IS_INITED(&vm.read_prs, p)) {
2316 
2317 			bc_parse_init(&vm.read_prs, p, fidx);
2318 
2319 			// Initialize this too because bc_vm_shutdown() expects them to be
2320 			// initialized togther.
2321 			bc_vec_init(&vm.read_buf, sizeof(char), BC_DTOR_NONE);
2322 		}
2323 		// This needs to be updated because the parser could have been used
2324 		// somewhere else
2325 		else bc_parse_updateFunc(&vm.read_prs, fidx);
2326 
2327 		bc_lex_file(&vm.read_prs.l, vm.file);
2328 
2329 		BC_SETJMP_LOCKED(err);
2330 
2331 		BC_SIG_UNLOCK;
2332 
2333 		// Parse.
2334 		bc_parse_text(&vm.read_prs, str, false);
2335 
2336 		BC_SIG_LOCK;
2337 		vm.expr(&vm.read_prs, BC_PARSE_NOCALL);
2338 
2339 		BC_UNSETJMP;
2340 
2341 		// We can just assert this here because
2342 		// dc should parse everything until EOF.
2343 		assert(vm.read_prs.l.t == BC_LEX_EOF);
2344 
2345 		BC_SIG_UNLOCK;
2346 	}
2347 
2348 	// Set the instruction pointer.
2349 	ip.idx = 0;
2350 	ip.len = p->results.len;
2351 	ip.func = fidx;
2352 
2353 	BC_SIG_LOCK;
2354 
2355 	// Pop the operand.
2356 	bc_vec_pop(&p->results);
2357 
2358 	// Tail call processing. This condition means that there is more on the
2359 	// execution stack, and we are at the end of the bytecode vector, and the
2360 	// last instruction is just a BC_INST_POP_EXEC, which would return.
2361 	if (p->stack.len > 1 && *bgn == len - 1 && code[*bgn] == BC_INST_POP_EXEC) {
2362 
2363 		size_t *call_ptr = bc_vec_top(&p->tail_calls);
2364 
2365 		// Add one to the tail call.
2366 		*call_ptr += 1;
2367 
2368 		// Pop the execution stack before pushing the new instruction pointer
2369 		// on.
2370 		bc_vec_pop(&p->stack);
2371 	}
2372 	// If not a tail call, just push a new one.
2373 	else bc_vec_push(&p->tail_calls, &ip.idx);
2374 
2375 	// Push the new function onto the execution stack and return.
2376 	bc_vec_push(&p->stack, &ip);
2377 
2378 	BC_SIG_UNLOCK;
2379 
2380 	return;
2381 
2382 err:
2383 	BC_SIG_MAYLOCK;
2384 
2385 	f = bc_vec_item(&p->fns, fidx);
2386 
2387 	// Make sure to erase the bytecode vector so dc knows it is not parsed.
2388 	bc_vec_popAll(&f->code);
2389 
2390 exit:
2391 	bc_vec_pop(&p->results);
2392 	BC_LONGJMP_CONT;
2393 }
2394 
2395 /**
2396  * Prints every item on the results stack, one per line.
2397  * @param p  The program.
2398  */
2399 static void bc_program_printStack(BcProgram *p) {
2400 
2401 	size_t idx;
2402 
2403 	for (idx = 0; idx < p->results.len; ++idx)
2404 		bc_program_print(p, BC_INST_PRINT, idx);
2405 }
2406 #endif // DC_ENABLED
2407 
2408 /**
2409  * Pushes the value of a global onto the results stack.
2410  * @param p     The program.
2411  * @param inst  Which global to push, as an instruction.
2412  */
2413 static void bc_program_pushGlobal(BcProgram *p, uchar inst) {
2414 
2415 	BcResultType t;
2416 
2417 	// Make sure the instruction is valid.
2418 	assert(inst >= BC_INST_IBASE && inst <= BC_INST_SCALE);
2419 
2420 	// Push the global.
2421 	t = inst - BC_INST_IBASE + BC_RESULT_IBASE;
2422 	bc_program_pushBigdig(p, p->globals[inst - BC_INST_IBASE], t);
2423 }
2424 
2425 /**
2426  * Pushes the value of a global setting onto the stack.
2427  * @param p     The program.
2428  * @param inst  Which global setting to push, as an instruction.
2429  */
2430 static void bc_program_globalSetting(BcProgram *p, uchar inst) {
2431 
2432 	BcBigDig val;
2433 
2434 	// Make sure the instruction is valid.
2435 	assert(inst >= BC_INST_LINE_LENGTH && inst <= BC_INST_LEADING_ZERO);
2436 
2437 	if (inst == BC_INST_LINE_LENGTH) val = (BcBigDig) vm.line_len;
2438 #if BC_ENABLED
2439 	else if (inst == BC_INST_GLOBAL_STACKS) val = (BC_G != 0);
2440 #endif // BC_ENABLED
2441 	else val = (BC_Z != 0);
2442 
2443 	// Push the global.
2444 	bc_program_pushBigdig(p, val, BC_RESULT_TEMP);
2445 }
2446 
2447 #if BC_ENABLE_EXTRA_MATH
2448 
2449 /**
2450  * Pushes the value of seed on the stack.
2451  * @param p  The program.
2452  */
2453 static void bc_program_pushSeed(BcProgram *p) {
2454 
2455 	BcResult *res;
2456 
2457 	res = bc_program_prepResult(p);
2458 	res->t = BC_RESULT_SEED;
2459 
2460 	BC_SIG_LOCK;
2461 
2462 	// We need 2*BC_RAND_NUM_SIZE because of the size of the state.
2463 	bc_num_init(&res->d.n, 2 * BC_RAND_NUM_SIZE);
2464 
2465 	BC_SIG_UNLOCK;
2466 
2467 	bc_num_createFromRNG(&res->d.n, &p->rng);
2468 }
2469 
2470 #endif // BC_ENABLE_EXTRA_MATH
2471 
2472 /**
2473  * Adds a function to the fns array. The function's ID must have already been
2474  * inserted into the map.
2475  * @param p       The program.
2476  * @param id_ptr  The ID of the function as inserted into the map.
2477  */
2478 static void bc_program_addFunc(BcProgram *p, BcId *id_ptr) {
2479 
2480 	BcInstPtr *ip;
2481 	BcFunc *f;
2482 
2483 	BC_SIG_ASSERT_LOCKED;
2484 
2485 	// Push and init.
2486 	f = bc_vec_pushEmpty(&p->fns);
2487 	bc_func_init(f, id_ptr->name);
2488 
2489 	// This is to make sure pointers are updated if the array was moved.
2490 	if (p->stack.len) {
2491 		ip = bc_vec_top(&p->stack);
2492 		bc_program_setVecs(p, (BcFunc*) bc_vec_item(&p->fns, ip->func));
2493 	}
2494 }
2495 
2496 size_t bc_program_insertFunc(BcProgram *p, const char *name) {
2497 
2498 	BcId *id_ptr;
2499 	bool new;
2500 	size_t idx;
2501 
2502 	BC_SIG_ASSERT_LOCKED;
2503 
2504 	assert(p != NULL && name != NULL);
2505 
2506 	// Insert into the map and get the resulting ID.
2507 	new = bc_map_insert(&p->fn_map, name, p->fns.len, &idx);
2508 	id_ptr = (BcId*) bc_vec_item(&p->fn_map, idx);
2509 	idx = id_ptr->idx;
2510 
2511 	// If the function is new...
2512 	if (new) {
2513 
2514 		// Add the function to the fns array.
2515 		bc_program_addFunc(p, id_ptr);
2516 	}
2517 #if BC_ENABLED
2518 	// bc has to reset the function because it's about to be redefined.
2519 	else if (BC_IS_BC) {
2520 		BcFunc *func = bc_vec_item(&p->fns, idx);
2521 		bc_func_reset(func);
2522 	}
2523 #endif // BC_ENABLED
2524 
2525 	return idx;
2526 }
2527 
2528 #ifndef NDEBUG
2529 void bc_program_free(BcProgram *p) {
2530 
2531 	size_t i;
2532 
2533 	BC_SIG_ASSERT_LOCKED;
2534 
2535 	assert(p != NULL);
2536 
2537 	// Free the globals stacks.
2538 	for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) bc_vec_free(p->globals_v + i);
2539 
2540 	bc_vec_free(&p->fns);
2541 	bc_vec_free(&p->fn_map);
2542 	bc_vec_free(&p->vars);
2543 	bc_vec_free(&p->var_map);
2544 	bc_vec_free(&p->arrs);
2545 	bc_vec_free(&p->arr_map);
2546 	bc_vec_free(&p->results);
2547 	bc_vec_free(&p->stack);
2548 
2549 #if BC_ENABLED
2550 	if (BC_IS_BC) bc_num_free(&p->last);
2551 #endif // BC_ENABLED
2552 
2553 #if BC_ENABLE_EXTRA_MATH
2554 	bc_rand_free(&p->rng);
2555 #endif // BC_ENABLE_EXTRA_MATH
2556 
2557 #if DC_ENABLED
2558 	if (BC_IS_DC) bc_vec_free(&p->tail_calls);
2559 #endif // DC_ENABLED
2560 }
2561 #endif // NDEBUG
2562 
2563 void bc_program_init(BcProgram *p) {
2564 
2565 	BcInstPtr ip;
2566 	size_t i;
2567 
2568 	BC_SIG_ASSERT_LOCKED;
2569 
2570 	assert(p != NULL);
2571 
2572 	// We want this clear.
2573 	memset(&ip, 0, sizeof(BcInstPtr));
2574 
2575 	// Setup the globals stacks and the current values.
2576 	for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) {
2577 
2578 		BcBigDig val = i == BC_PROG_GLOBALS_SCALE ? 0 : BC_BASE;
2579 
2580 		bc_vec_init(p->globals_v + i, sizeof(BcBigDig), BC_DTOR_NONE);
2581 		bc_vec_push(p->globals_v + i, &val);
2582 
2583 		p->globals[i] = val;
2584 	}
2585 
2586 #if DC_ENABLED
2587 	// dc-only setup.
2588 	if (BC_IS_DC) {
2589 
2590 		bc_vec_init(&p->tail_calls, sizeof(size_t), BC_DTOR_NONE);
2591 
2592 		// We want an item for the main function on the tail call stack.
2593 		i = 0;
2594 		bc_vec_push(&p->tail_calls, &i);
2595 	}
2596 #endif // DC_ENABLED
2597 
2598 	bc_num_setup(&p->strmb, p->strmb_num, BC_NUM_BIGDIG_LOG10);
2599 	bc_num_bigdig2num(&p->strmb, BC_NUM_STREAM_BASE);
2600 
2601 #if BC_ENABLE_EXTRA_MATH
2602 	// We need to initialize srand() just in case /dev/urandom and /dev/random
2603 	// are not available.
2604 	srand((unsigned int) time(NULL));
2605 	bc_rand_init(&p->rng);
2606 #endif // BC_ENABLE_EXTRA_MATH
2607 
2608 #if BC_ENABLED
2609 	if (BC_IS_BC) bc_num_init(&p->last, BC_NUM_DEF_SIZE);
2610 #endif // BC_ENABLED
2611 
2612 #ifndef NDEBUG
2613 	bc_vec_init(&p->fns, sizeof(BcFunc), BC_DTOR_FUNC);
2614 #else // NDEBUG
2615 	bc_vec_init(&p->fns, sizeof(BcFunc), BC_DTOR_NONE);
2616 #endif // NDEBUG
2617 	bc_map_init(&p->fn_map);
2618 	bc_program_insertFunc(p, bc_func_main);
2619 	bc_program_insertFunc(p, bc_func_read);
2620 
2621 	bc_vec_init(&p->vars, sizeof(BcVec), BC_DTOR_VEC);
2622 	bc_map_init(&p->var_map);
2623 
2624 	bc_vec_init(&p->arrs, sizeof(BcVec), BC_DTOR_VEC);
2625 	bc_map_init(&p->arr_map);
2626 
2627 	bc_vec_init(&p->results, sizeof(BcResult), BC_DTOR_RESULT);
2628 
2629 	// Push the first instruction pointer onto the execution stack.
2630 	bc_vec_init(&p->stack, sizeof(BcInstPtr), BC_DTOR_NONE);
2631 	bc_vec_push(&p->stack, &ip);
2632 
2633 	// Make sure the pointers are properly set up.
2634 	bc_program_setVecs(p, (BcFunc*) bc_vec_item(&p->fns, BC_PROG_MAIN));
2635 
2636 	assert(p->consts != NULL && p->strs != NULL);
2637 }
2638 
2639 void bc_program_reset(BcProgram *p) {
2640 
2641 	BcFunc *f;
2642 	BcInstPtr *ip;
2643 
2644 	BC_SIG_ASSERT_LOCKED;
2645 
2646 	// Pop all but the last execution and all results.
2647 	bc_vec_npop(&p->stack, p->stack.len - 1);
2648 	bc_vec_popAll(&p->results);
2649 
2650 #if BC_ENABLED
2651 	// Clear the globals' stacks.
2652 	if (BC_G) bc_program_popGlobals(p, true);
2653 #endif // BC_ENABLED
2654 
2655 	// Clear the bytecode vector of the main function.
2656 	f = bc_vec_item(&p->fns, BC_PROG_MAIN);
2657 	bc_vec_npop(&f->code, f->code.len);
2658 
2659 	// Reset the instruction pointer.
2660 	ip = bc_vec_top(&p->stack);
2661 	bc_program_setVecs(p, f);
2662 	memset(ip, 0, sizeof(BcInstPtr));
2663 
2664 	// Write the ready message for a signal, and clear the signal.
2665 	if (vm.sig) {
2666 		bc_file_write(&vm.fout, bc_flush_none, bc_program_ready_msg,
2667 		              bc_program_ready_msg_len);
2668 		bc_file_flush(&vm.fout, bc_flush_err);
2669 		vm.sig = 0;
2670 	}
2671 }
2672 
2673 void bc_program_exec(BcProgram *p) {
2674 
2675 	size_t idx;
2676 	BcResult r, *ptr;
2677 	BcInstPtr *ip;
2678 	BcFunc *func;
2679 	char *code;
2680 	bool cond = false;
2681 	uchar inst;
2682 #if BC_ENABLED
2683 	BcNum *num;
2684 #endif // BC_ENABLED
2685 #if !BC_HAS_COMPUTED_GOTO
2686 #ifndef NDEBUG
2687 	size_t jmp_bufs_len;
2688 #endif // NDEBUG
2689 #endif // !BC_HAS_COMPUTED_GOTO
2690 
2691 #if BC_HAS_COMPUTED_GOTO
2692 	BC_PROG_LBLS;
2693 	BC_PROG_LBLS_ASSERT;
2694 
2695 	// BC_INST_INVALID is a marker for the end so that we don't have to have an
2696 	// execution loop.
2697 	func = (BcFunc*) bc_vec_item(&p->fns, BC_PROG_MAIN);
2698 	bc_vec_pushByte(&func->code, BC_INST_INVALID);
2699 #endif // BC_HAS_COMPUTED_GOTO
2700 
2701 	ip = bc_vec_top(&p->stack);
2702 	func = (BcFunc*) bc_vec_item(&p->fns, ip->func);
2703 	code = func->code.v;
2704 
2705 	// Ensure the pointers are correct.
2706 	BC_SIG_LOCK;
2707 	bc_program_setVecs(p, func);
2708 	BC_SIG_UNLOCK;
2709 
2710 #if !BC_HAS_COMPUTED_GOTO
2711 
2712 #ifndef NDEBUG
2713 	jmp_bufs_len = vm.jmp_bufs.len;
2714 #endif // NDEBUG
2715 
2716 	// This loop is the heart of the execution engine. It *is* the engine. For
2717 	// computed goto, it is ignored.
2718 	while (ip->idx < func->code.len)
2719 #endif // !BC_HAS_COMPUTED_GOTO
2720 	{
2721 
2722 		BC_SIG_ASSERT_NOT_LOCKED;
2723 
2724 #if BC_HAS_COMPUTED_GOTO
2725 
2726 		BC_PROG_JUMP(inst, code, ip);
2727 
2728 #else // BC_HAS_COMPUTED_GOTO
2729 
2730 		// Get the next instruction and increment the index.
2731 		inst = (uchar) code[(ip->idx)++];
2732 
2733 #endif // BC_HAS_COMPUTED_GOTO
2734 
2735 #if BC_DEBUG_CODE
2736 		bc_file_printf(&vm.ferr, "inst: %s\n", bc_inst_names[inst]);
2737 		bc_file_flush(&vm.ferr, bc_flush_none);
2738 #endif // BC_DEBUG_CODE
2739 
2740 #if !BC_HAS_COMPUTED_GOTO
2741 		switch (inst)
2742 #endif // !BC_HAS_COMPUTED_GOTO
2743 		{
2744 
2745 #if BC_ENABLED
2746 			// This just sets up the condition for the unconditional jump below,
2747 			// which checks the condition, if necessary.
2748 			BC_PROG_LBL(BC_INST_JUMP_ZERO):
2749 			{
2750 				bc_program_prep(p, &ptr, &num, 0);
2751 
2752 				cond = !bc_num_cmpZero(num);
2753 				bc_vec_pop(&p->results);
2754 
2755 				BC_PROG_DIRECT_JUMP(BC_INST_JUMP)
2756 			}
2757 			// Fallthrough.
2758 			BC_PROG_FALLTHROUGH
2759 
2760 			BC_PROG_LBL(BC_INST_JUMP):
2761 			{
2762 				idx = bc_program_index(code, &ip->idx);
2763 
2764 				// If a jump is required...
2765 				if (inst == BC_INST_JUMP || cond) {
2766 
2767 					// Get the address to jump to.
2768 					size_t *addr = bc_vec_item(&func->labels, idx);
2769 
2770 					// If this fails, then the parser failed to set up the
2771 					// labels correctly.
2772 					assert(*addr != SIZE_MAX);
2773 
2774 					// Set the new address.
2775 					ip->idx = *addr;
2776 				}
2777 
2778 				BC_PROG_JUMP(inst, code, ip);
2779 			}
2780 
2781 			BC_PROG_LBL(BC_INST_CALL):
2782 			{
2783 				assert(BC_IS_BC);
2784 
2785 				bc_program_call(p, code, &ip->idx);
2786 
2787 				// Because we changed the execution stack and where we are
2788 				// executing, we have to update all of this.
2789 				BC_SIG_LOCK;
2790 				ip = bc_vec_top(&p->stack);
2791 				func = bc_vec_item(&p->fns, ip->func);
2792 				code = func->code.v;
2793 				bc_program_setVecs(p, func);
2794 				BC_SIG_UNLOCK;
2795 
2796 				BC_PROG_JUMP(inst, code, ip);
2797 			}
2798 
2799 			BC_PROG_LBL(BC_INST_INC):
2800 			BC_PROG_LBL(BC_INST_DEC):
2801 			{
2802 				bc_program_incdec(p, inst);
2803 				BC_PROG_JUMP(inst, code, ip);
2804 			}
2805 
2806 			BC_PROG_LBL(BC_INST_HALT):
2807 			{
2808 				vm.status = BC_STATUS_QUIT;
2809 
2810 				// Just jump out. The jump series will take care of everything.
2811 				BC_JMP;
2812 
2813 				BC_PROG_JUMP(inst, code, ip);
2814 			}
2815 
2816 			BC_PROG_LBL(BC_INST_RET):
2817 			BC_PROG_LBL(BC_INST_RET0):
2818 			BC_PROG_LBL(BC_INST_RET_VOID):
2819 			{
2820 				bc_program_return(p, inst);
2821 
2822 				// Because we changed the execution stack and where we are
2823 				// executing, we have to update all of this.
2824 				BC_SIG_LOCK;
2825 				ip = bc_vec_top(&p->stack);
2826 				func = bc_vec_item(&p->fns, ip->func);
2827 				code = func->code.v;
2828 				bc_program_setVecs(p, func);
2829 				BC_SIG_UNLOCK;
2830 
2831 				BC_PROG_JUMP(inst, code, ip);
2832 			}
2833 #endif // BC_ENABLED
2834 
2835 			BC_PROG_LBL(BC_INST_BOOL_OR):
2836 			BC_PROG_LBL(BC_INST_BOOL_AND):
2837 			BC_PROG_LBL(BC_INST_REL_EQ):
2838 			BC_PROG_LBL(BC_INST_REL_LE):
2839 			BC_PROG_LBL(BC_INST_REL_GE):
2840 			BC_PROG_LBL(BC_INST_REL_NE):
2841 			BC_PROG_LBL(BC_INST_REL_LT):
2842 			BC_PROG_LBL(BC_INST_REL_GT):
2843 			{
2844 				bc_program_logical(p, inst);
2845 				BC_PROG_JUMP(inst, code, ip);
2846 			}
2847 
2848 			BC_PROG_LBL(BC_INST_READ):
2849 			{
2850 				// We want to flush output before
2851 				// this in case there is a prompt.
2852 				bc_file_flush(&vm.fout, bc_flush_save);
2853 
2854 				bc_program_read(p);
2855 
2856 				// Because we changed the execution stack and where we are
2857 				// executing, we have to update all of this.
2858 				BC_SIG_LOCK;
2859 				ip = bc_vec_top(&p->stack);
2860 				func = bc_vec_item(&p->fns, ip->func);
2861 				code = func->code.v;
2862 				bc_program_setVecs(p, func);
2863 				BC_SIG_UNLOCK;
2864 
2865 				BC_PROG_JUMP(inst, code, ip);
2866 			}
2867 
2868 #if BC_ENABLE_EXTRA_MATH
2869 			BC_PROG_LBL(BC_INST_RAND):
2870 			{
2871 				bc_program_rand(p);
2872 				BC_PROG_JUMP(inst, code, ip);
2873 			}
2874 #endif // BC_ENABLE_EXTRA_MATH
2875 
2876 			BC_PROG_LBL(BC_INST_MAXIBASE):
2877 			BC_PROG_LBL(BC_INST_MAXOBASE):
2878 			BC_PROG_LBL(BC_INST_MAXSCALE):
2879 #if BC_ENABLE_EXTRA_MATH
2880 			BC_PROG_LBL(BC_INST_MAXRAND):
2881 #endif // BC_ENABLE_EXTRA_MATH
2882 			{
2883 				BcBigDig dig = vm.maxes[inst - BC_INST_MAXIBASE];
2884 				bc_program_pushBigdig(p, dig, BC_RESULT_TEMP);
2885 				BC_PROG_JUMP(inst, code, ip);
2886 			}
2887 
2888 			BC_PROG_LBL(BC_INST_LINE_LENGTH):
2889 #if BC_ENABLED
2890 			BC_PROG_LBL(BC_INST_GLOBAL_STACKS):
2891 #endif // BC_ENABLED
2892 			BC_PROG_LBL(BC_INST_LEADING_ZERO):
2893 			{
2894 				bc_program_globalSetting(p, inst);
2895 				BC_PROG_JUMP(inst, code, ip);
2896 			}
2897 
2898 			BC_PROG_LBL(BC_INST_VAR):
2899 			{
2900 				bc_program_pushVar(p, code, &ip->idx, false, false);
2901 				BC_PROG_JUMP(inst, code, ip);
2902 			}
2903 
2904 			BC_PROG_LBL(BC_INST_ARRAY_ELEM):
2905 			BC_PROG_LBL(BC_INST_ARRAY):
2906 			{
2907 				bc_program_pushArray(p, code, &ip->idx, inst);
2908 				BC_PROG_JUMP(inst, code, ip);
2909 			}
2910 
2911 			BC_PROG_LBL(BC_INST_IBASE):
2912 			BC_PROG_LBL(BC_INST_SCALE):
2913 			BC_PROG_LBL(BC_INST_OBASE):
2914 			{
2915 				bc_program_pushGlobal(p, inst);
2916 				BC_PROG_JUMP(inst, code, ip);
2917 			}
2918 
2919 #if BC_ENABLE_EXTRA_MATH
2920 			BC_PROG_LBL(BC_INST_SEED):
2921 			{
2922 				bc_program_pushSeed(p);
2923 				BC_PROG_JUMP(inst, code, ip);
2924 			}
2925 #endif // BC_ENABLE_EXTRA_MATH
2926 
2927 			BC_PROG_LBL(BC_INST_LENGTH):
2928 			BC_PROG_LBL(BC_INST_SCALE_FUNC):
2929 			BC_PROG_LBL(BC_INST_SQRT):
2930 			BC_PROG_LBL(BC_INST_ABS):
2931 #if BC_ENABLE_EXTRA_MATH
2932 			BC_PROG_LBL(BC_INST_IRAND):
2933 #endif // BC_ENABLE_EXTRA_MATH
2934 			{
2935 				bc_program_builtin(p, inst);
2936 				BC_PROG_JUMP(inst, code, ip);
2937 			}
2938 
2939 			BC_PROG_LBL(BC_INST_ASCIIFY):
2940 			{
2941 				bc_program_asciify(p, ip->func);
2942 
2943 				// Because we changed the execution stack and where we are
2944 				// executing, we have to update all of this.
2945 				BC_SIG_LOCK;
2946 				ip = bc_vec_top(&p->stack);
2947 				func = bc_vec_item(&p->fns, ip->func);
2948 				code = func->code.v;
2949 				bc_program_setVecs(p, func);
2950 				BC_SIG_UNLOCK;
2951 
2952 				BC_PROG_JUMP(inst, code, ip);
2953 			}
2954 
2955 			BC_PROG_LBL(BC_INST_NUM):
2956 			{
2957 				bc_program_const(p, code, &ip->idx);
2958 				BC_PROG_JUMP(inst, code, ip);
2959 			}
2960 
2961 			BC_PROG_LBL(BC_INST_ZERO):
2962 			BC_PROG_LBL(BC_INST_ONE):
2963 #if BC_ENABLED
2964 			BC_PROG_LBL(BC_INST_LAST):
2965 #endif // BC_ENABLED
2966 			{
2967 				r.t = BC_RESULT_ZERO + (inst - BC_INST_ZERO);
2968 				bc_vec_push(&p->results, &r);
2969 				BC_PROG_JUMP(inst, code, ip);
2970 			}
2971 
2972 			BC_PROG_LBL(BC_INST_PRINT):
2973 			BC_PROG_LBL(BC_INST_PRINT_POP):
2974 #if BC_ENABLED
2975 			BC_PROG_LBL(BC_INST_PRINT_STR):
2976 #endif // BC_ENABLED
2977 			{
2978 				bc_program_print(p, inst, 0);
2979 
2980 				// We want to flush right away to save the output for history,
2981 				// if history must preserve it when taking input.
2982 				bc_file_flush(&vm.fout, bc_flush_save);
2983 
2984 				BC_PROG_JUMP(inst, code, ip);
2985 			}
2986 
2987 			BC_PROG_LBL(BC_INST_STR):
2988 			{
2989 				// Set up the result and push.
2990 				r.t = BC_RESULT_STR;
2991 				bc_num_clear(&r.d.n);
2992 				r.d.n.rdx = bc_program_index(code, &ip->idx);
2993 				r.d.n.scale = bc_program_index(code, &ip->idx);
2994 				bc_vec_push(&p->results, &r);
2995 				BC_PROG_JUMP(inst, code, ip);
2996 			}
2997 
2998 			BC_PROG_LBL(BC_INST_POWER):
2999 			BC_PROG_LBL(BC_INST_MULTIPLY):
3000 			BC_PROG_LBL(BC_INST_DIVIDE):
3001 			BC_PROG_LBL(BC_INST_MODULUS):
3002 			BC_PROG_LBL(BC_INST_PLUS):
3003 			BC_PROG_LBL(BC_INST_MINUS):
3004 #if BC_ENABLE_EXTRA_MATH
3005 			BC_PROG_LBL(BC_INST_PLACES):
3006 			BC_PROG_LBL(BC_INST_LSHIFT):
3007 			BC_PROG_LBL(BC_INST_RSHIFT):
3008 #endif // BC_ENABLE_EXTRA_MATH
3009 			{
3010 				bc_program_op(p, inst);
3011 				BC_PROG_JUMP(inst, code, ip);
3012 			}
3013 
3014 			BC_PROG_LBL(BC_INST_NEG):
3015 			BC_PROG_LBL(BC_INST_BOOL_NOT):
3016 #if BC_ENABLE_EXTRA_MATH
3017 			BC_PROG_LBL(BC_INST_TRUNC):
3018 #endif // BC_ENABLE_EXTRA_MATH
3019 			{
3020 				bc_program_unary(p, inst);
3021 				BC_PROG_JUMP(inst, code, ip);
3022 			}
3023 
3024 #if BC_ENABLED
3025 			BC_PROG_LBL(BC_INST_ASSIGN_POWER):
3026 			BC_PROG_LBL(BC_INST_ASSIGN_MULTIPLY):
3027 			BC_PROG_LBL(BC_INST_ASSIGN_DIVIDE):
3028 			BC_PROG_LBL(BC_INST_ASSIGN_MODULUS):
3029 			BC_PROG_LBL(BC_INST_ASSIGN_PLUS):
3030 			BC_PROG_LBL(BC_INST_ASSIGN_MINUS):
3031 #if BC_ENABLE_EXTRA_MATH
3032 			BC_PROG_LBL(BC_INST_ASSIGN_PLACES):
3033 			BC_PROG_LBL(BC_INST_ASSIGN_LSHIFT):
3034 			BC_PROG_LBL(BC_INST_ASSIGN_RSHIFT):
3035 #endif // BC_ENABLE_EXTRA_MATH
3036 			BC_PROG_LBL(BC_INST_ASSIGN):
3037 			BC_PROG_LBL(BC_INST_ASSIGN_POWER_NO_VAL):
3038 			BC_PROG_LBL(BC_INST_ASSIGN_MULTIPLY_NO_VAL):
3039 			BC_PROG_LBL(BC_INST_ASSIGN_DIVIDE_NO_VAL):
3040 			BC_PROG_LBL(BC_INST_ASSIGN_MODULUS_NO_VAL):
3041 			BC_PROG_LBL(BC_INST_ASSIGN_PLUS_NO_VAL):
3042 			BC_PROG_LBL(BC_INST_ASSIGN_MINUS_NO_VAL):
3043 #if BC_ENABLE_EXTRA_MATH
3044 			BC_PROG_LBL(BC_INST_ASSIGN_PLACES_NO_VAL):
3045 			BC_PROG_LBL(BC_INST_ASSIGN_LSHIFT_NO_VAL):
3046 			BC_PROG_LBL(BC_INST_ASSIGN_RSHIFT_NO_VAL):
3047 #endif // BC_ENABLE_EXTRA_MATH
3048 #endif // BC_ENABLED
3049 			BC_PROG_LBL(BC_INST_ASSIGN_NO_VAL):
3050 			{
3051 				bc_program_assign(p, inst);
3052 				BC_PROG_JUMP(inst, code, ip);
3053 			}
3054 
3055 			BC_PROG_LBL(BC_INST_POP):
3056 			{
3057 #ifndef BC_PROG_NO_STACK_CHECK
3058 				// dc must do a stack check, but bc does not.
3059 				if (BC_IS_DC) {
3060 					if (BC_ERR(!BC_PROG_STACK(&p->results, 1)))
3061 						bc_err(BC_ERR_EXEC_STACK);
3062 				}
3063 #endif // BC_PROG_NO_STACK_CHECK
3064 
3065 				assert(BC_PROG_STACK(&p->results, 1));
3066 
3067 				bc_vec_pop(&p->results);
3068 
3069 				BC_PROG_JUMP(inst, code, ip);
3070 			}
3071 
3072 			BC_PROG_LBL(BC_INST_SWAP):
3073 			{
3074 				BcResult *ptr2;
3075 
3076 				// Check the stack.
3077 				if (BC_ERR(!BC_PROG_STACK(&p->results, 2)))
3078 					bc_err(BC_ERR_EXEC_STACK);
3079 
3080 				assert(BC_PROG_STACK(&p->results, 2));
3081 
3082 				// Get the two items.
3083 				ptr = bc_vec_item_rev(&p->results, 0);
3084 				ptr2 = bc_vec_item_rev(&p->results, 1);
3085 
3086 				// Swap. It's just easiest to do it this way.
3087 				memcpy(&r, ptr, sizeof(BcResult));
3088 				memcpy(ptr, ptr2, sizeof(BcResult));
3089 				memcpy(ptr2, &r, sizeof(BcResult));
3090 
3091 				BC_PROG_JUMP(inst, code, ip);
3092 			}
3093 
3094 			BC_PROG_LBL(BC_INST_MODEXP):
3095 			{
3096 				bc_program_modexp(p);
3097 				BC_PROG_JUMP(inst, code, ip);
3098 			}
3099 
3100 			BC_PROG_LBL(BC_INST_DIVMOD):
3101 			{
3102 				bc_program_divmod(p);
3103 				BC_PROG_JUMP(inst, code, ip);
3104 			}
3105 
3106 			BC_PROG_LBL(BC_INST_PRINT_STREAM):
3107 			{
3108 				bc_program_printStream(p);
3109 				BC_PROG_JUMP(inst, code, ip);
3110 			}
3111 
3112 #if DC_ENABLED
3113 			BC_PROG_LBL(BC_INST_POP_EXEC):
3114 			{
3115 				// If this fails, the dc parser got something wrong.
3116 				assert(BC_PROG_STACK(&p->stack, 2));
3117 
3118 				// Pop the execution stack and tail call stack.
3119 				bc_vec_pop(&p->stack);
3120 				bc_vec_pop(&p->tail_calls);
3121 
3122 				// Because we changed the execution stack and where we are
3123 				// executing, we have to update all of this.
3124 				BC_SIG_LOCK;
3125 				ip = bc_vec_top(&p->stack);
3126 				func = bc_vec_item(&p->fns, ip->func);
3127 				code = func->code.v;
3128 				bc_program_setVecs(p, func);
3129 				BC_SIG_UNLOCK;
3130 
3131 				BC_PROG_JUMP(inst, code, ip);
3132 			}
3133 
3134 			BC_PROG_LBL(BC_INST_EXECUTE):
3135 			BC_PROG_LBL(BC_INST_EXEC_COND):
3136 			{
3137 				cond = (inst == BC_INST_EXEC_COND);
3138 
3139 				bc_program_execStr(p, code, &ip->idx, cond, func->code.len);
3140 
3141 				// Because we changed the execution stack and where we are
3142 				// executing, we have to update all of this.
3143 				BC_SIG_LOCK;
3144 				ip = bc_vec_top(&p->stack);
3145 				func = bc_vec_item(&p->fns, ip->func);
3146 				code = func->code.v;
3147 				bc_program_setVecs(p, func);
3148 				BC_SIG_UNLOCK;
3149 
3150 				BC_PROG_JUMP(inst, code, ip);
3151 			}
3152 
3153 			BC_PROG_LBL(BC_INST_PRINT_STACK):
3154 			{
3155 				bc_program_printStack(p);
3156 				BC_PROG_JUMP(inst, code, ip);
3157 			}
3158 
3159 			BC_PROG_LBL(BC_INST_CLEAR_STACK):
3160 			{
3161 				bc_vec_popAll(&p->results);
3162 				BC_PROG_JUMP(inst, code, ip);
3163 			}
3164 
3165 			BC_PROG_LBL(BC_INST_REG_STACK_LEN):
3166 			{
3167 				bc_program_regStackLen(p, code, &ip->idx);
3168 				BC_PROG_JUMP(inst, code, ip);
3169 			}
3170 
3171 			BC_PROG_LBL(BC_INST_STACK_LEN):
3172 			{
3173 				bc_program_stackLen(p);
3174 				BC_PROG_JUMP(inst, code, ip);
3175 			}
3176 
3177 			BC_PROG_LBL(BC_INST_DUPLICATE):
3178 			{
3179 				// Check the stack.
3180 				if (BC_ERR(!BC_PROG_STACK(&p->results, 1)))
3181 					bc_err(BC_ERR_EXEC_STACK);
3182 
3183 				assert(BC_PROG_STACK(&p->results, 1));
3184 
3185 				// Get the top of the stack.
3186 				ptr = bc_vec_top(&p->results);
3187 
3188 				BC_SIG_LOCK;
3189 
3190 				// Copy and push.
3191 				bc_result_copy(&r, ptr);
3192 				bc_vec_push(&p->results, &r);
3193 
3194 				BC_SIG_UNLOCK;
3195 
3196 				BC_PROG_JUMP(inst, code, ip);
3197 			}
3198 
3199 			BC_PROG_LBL(BC_INST_LOAD):
3200 			BC_PROG_LBL(BC_INST_PUSH_VAR):
3201 			{
3202 				bool copy = (inst == BC_INST_LOAD);
3203 				bc_program_pushVar(p, code, &ip->idx, true, copy);
3204 				BC_PROG_JUMP(inst, code, ip);
3205 			}
3206 
3207 			BC_PROG_LBL(BC_INST_PUSH_TO_VAR):
3208 			{
3209 				idx = bc_program_index(code, &ip->idx);
3210 				bc_program_copyToVar(p, idx, BC_TYPE_VAR, true);
3211 				BC_PROG_JUMP(inst, code, ip);
3212 			}
3213 
3214 			BC_PROG_LBL(BC_INST_QUIT):
3215 			BC_PROG_LBL(BC_INST_NQUIT):
3216 			{
3217 				bc_program_nquit(p, inst);
3218 
3219 				// Because we changed the execution stack and where we are
3220 				// executing, we have to update all of this.
3221 				BC_SIG_LOCK;
3222 				ip = bc_vec_top(&p->stack);
3223 				func = bc_vec_item(&p->fns, ip->func);
3224 				code = func->code.v;
3225 				bc_program_setVecs(p, func);
3226 				BC_SIG_UNLOCK;
3227 
3228 				BC_PROG_JUMP(inst, code, ip);
3229 			}
3230 
3231 			BC_PROG_LBL(BC_INST_EXEC_STACK_LEN):
3232 			{
3233 				bc_program_execStackLen(p);
3234 				BC_PROG_JUMP(inst, code, ip);
3235 			}
3236 #endif // DC_ENABLED
3237 
3238 #if BC_HAS_COMPUTED_GOTO
3239 			BC_PROG_LBL(BC_INST_INVALID):
3240 			{
3241 				return;
3242 			}
3243 #else // BC_HAS_COMPUTED_GOTO
3244 			default:
3245 			{
3246 				BC_UNREACHABLE
3247 #ifndef NDEBUG
3248 				abort();
3249 #endif // NDEBUG
3250 			}
3251 #endif // BC_HAS_COMPUTED_GOTO
3252 		}
3253 
3254 #if !BC_HAS_COMPUTED_GOTO
3255 #ifndef NDEBUG
3256 		// This is to allow me to use a debugger to see the last instruction,
3257 		// which will point to which function was the problem. But it's also a
3258 		// good smoke test for error handling changes.
3259 		assert(jmp_bufs_len == vm.jmp_bufs.len);
3260 #endif // NDEBUG
3261 #endif // !BC_HAS_COMPUTED_GOTO
3262 	}
3263 }
3264 
3265 #if BC_DEBUG_CODE
3266 #if BC_ENABLED && DC_ENABLED
3267 void bc_program_printStackDebug(BcProgram *p) {
3268 	bc_file_puts(&vm.fout, bc_flush_err, "-------------- Stack ----------\n");
3269 	bc_program_printStack(p);
3270 	bc_file_puts(&vm.fout, bc_flush_err, "-------------- Stack End ------\n");
3271 }
3272 
3273 static void bc_program_printIndex(const char *restrict code,
3274                                   size_t *restrict bgn)
3275 {
3276 	uchar byte, i, bytes = (uchar) code[(*bgn)++];
3277 	ulong val = 0;
3278 
3279 	for (byte = 1, i = 0; byte && i < bytes; ++i) {
3280 		byte = (uchar) code[(*bgn)++];
3281 		if (byte) val |= ((ulong) byte) << (CHAR_BIT * i);
3282 	}
3283 
3284 	bc_vm_printf(" (%lu) ", val);
3285 }
3286 
3287 static void bc_program_printStr(const BcProgram *p, const char *restrict code,
3288                          size_t *restrict bgn)
3289 {
3290 	size_t idx = bc_program_index(code, bgn);
3291 	char *s;
3292 
3293 	s = *((char**) bc_vec_item(p->strs, idx));
3294 
3295 	bc_vm_printf(" (\"%s\") ", s);
3296 }
3297 
3298 void bc_program_printInst(const BcProgram *p, const char *restrict code,
3299                           size_t *restrict bgn)
3300 {
3301 	uchar inst = (uchar) code[(*bgn)++];
3302 
3303 	bc_vm_printf("Inst[%zu]: %s [%lu]; ", *bgn - 1,
3304 	             bc_inst_names[inst], (unsigned long) inst);
3305 
3306 	if (inst == BC_INST_VAR || inst == BC_INST_ARRAY_ELEM ||
3307 	    inst == BC_INST_ARRAY)
3308 	{
3309 		bc_program_printIndex(code, bgn);
3310 	}
3311 	else if (inst == BC_INST_STR) bc_program_printStr(p, code, bgn);
3312 	else if (inst == BC_INST_NUM) {
3313 		size_t idx = bc_program_index(code, bgn);
3314 		BcConst *c = bc_vec_item(p->consts, idx);
3315 		bc_vm_printf("(%s)", c->val);
3316 	}
3317 	else if (inst == BC_INST_CALL ||
3318 	         (inst > BC_INST_STR && inst <= BC_INST_JUMP_ZERO))
3319 	{
3320 		bc_program_printIndex(code, bgn);
3321 		if (inst == BC_INST_CALL) bc_program_printIndex(code, bgn);
3322 	}
3323 
3324 	bc_vm_putchar('\n', bc_flush_err);
3325 }
3326 
3327 void bc_program_code(const BcProgram* p) {
3328 
3329 	BcFunc *f;
3330 	char *code;
3331 	BcInstPtr ip;
3332 	size_t i;
3333 
3334 	for (i = 0; i < p->fns.len; ++i) {
3335 
3336 		ip.idx = ip.len = 0;
3337 		ip.func = i;
3338 
3339 		f = bc_vec_item(&p->fns, ip.func);
3340 		code = f->code.v;
3341 
3342 		bc_vm_printf("func[%zu]:\n", ip.func);
3343 		while (ip.idx < f->code.len) bc_program_printInst(p, code, &ip.idx);
3344 		bc_file_puts(&vm.fout, bc_flush_err, "\n\n");
3345 	}
3346 }
3347 #endif // BC_ENABLED && DC_ENABLED
3348 #endif // BC_DEBUG_CODE
3349