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