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