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