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