aboutsummaryrefslogtreecommitdiff
path: root/src/program.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/program.c')
-rw-r--r--src/program.c53
1 files changed, 47 insertions, 6 deletions
diff --git a/src/program.c b/src/program.c
index 1ff9c24f323b..bc5b88011638 100644
--- a/src/program.c
+++ b/src/program.c
@@ -55,6 +55,7 @@
* @param f The new function.
*/
static inline void bc_program_setVecs(BcProgram *p, BcFunc *f) {
+ BC_SIG_ASSERT_LOCKED;
p->consts = &f->consts;
p->strs = &f->strs;
}
@@ -152,6 +153,8 @@ static void bc_program_popGlobals(BcProgram *p, bool reset) {
size_t i;
+ BC_SIG_ASSERT_LOCKED;
+
for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) {
BcVec *v = p->globals_v + i;
bc_vec_npop(v, reset ? v->len - 1 : 1);
@@ -238,12 +241,12 @@ size_t bc_program_search(BcProgram *p, const char *id, bool var) {
BcVec *v, *map;
size_t i;
+ BC_SIG_ASSERT_LOCKED;
+
// Grab the right vector and map.
v = var ? &p->vars : &p->arrs;
map = var ? &p->var_map : &p->arr_map;
- BC_SIG_LOCK;
-
// We do an insert because the variable might not exist yet. This is because
// the parser calls this function. If the insert succeeds, we create a stack
// for the variable/array. But regardless, bc_map_insert() gives us the
@@ -253,8 +256,6 @@ size_t bc_program_search(BcProgram *p, const char *id, bool var) {
bc_array_init(temp, var);
}
- BC_SIG_UNLOCK;
-
return ((BcId*) bc_vec_item(map, i))->idx;
}
@@ -711,7 +712,9 @@ static void bc_program_read(BcProgram *p) {
// Parse *one* expression.
bc_parse_text(&vm.read_prs, vm.read_buf.v, false);
+ BC_SIG_LOCK;
vm.expr(&vm.read_prs, BC_PARSE_NOREAD | BC_PARSE_NEEDVAL);
+ BC_SIG_UNLOCK;
// We *must* have a valid expression. A semicolon cannot end an expression,
// although EOF can.
@@ -736,6 +739,9 @@ static void bc_program_read(BcProgram *p) {
// We want a return instruction to simplify things.
bc_vec_pushByte(&f->code, vm.read_ret);
+
+ // This lock is here to make sure dc's tail calls are the same length.
+ BC_SIG_LOCK;
bc_vec_push(&p->stack, &ip);
#if DC_ENABLED
@@ -784,6 +790,9 @@ static void bc_program_printChars(const char *str) {
const char *nl;
size_t len = vm.nchars + strlen(str);
+ sig_atomic_t lock;
+
+ BC_SIG_TRYLOCK(lock);
bc_file_puts(&vm.fout, bc_flush_save, str);
@@ -794,6 +803,8 @@ static void bc_program_printChars(const char *str) {
if (nl != NULL) len = strlen(nl + 1);
vm.nchars = len > UINT16_MAX ? UINT16_MAX : (uint16_t) len;
+
+ BC_SIG_TRYUNLOCK(lock);
}
/**
@@ -830,7 +841,11 @@ static void bc_program_printString(const char *restrict str) {
if (ptr != NULL) {
// We need to specially handle a newline.
- if (c == 'n') vm.nchars = UINT16_MAX;
+ if (c == 'n') {
+ BC_SIG_LOCK;
+ vm.nchars = UINT16_MAX;
+ BC_SIG_UNLOCK;
+ }
// Grab the actual character.
c = bc_program_esc_seqs[(size_t) (ptr - bc_program_esc_chars)];
@@ -1770,6 +1785,8 @@ static void bc_program_return(BcProgram *p, uchar inst) {
bc_vec_pop(v);
}
+ BC_SIG_LOCK;
+
// When we retire, pop all of the unused results.
bc_program_retire(p, 1, nresults);
@@ -1778,6 +1795,8 @@ static void bc_program_return(BcProgram *p, uchar inst) {
// Pop the stack. This is what causes the function to actually "return."
bc_vec_pop(&p->stack);
+
+ BC_SIG_UNLOCK;
}
#endif // BC_ENABLED
@@ -2184,8 +2203,10 @@ static void bc_program_nquit(BcProgram *p, uchar inst) {
// because these are for tail calls. That means that any executions that
// we would not have quit in that position on the stack would have quit
// anyway.
+ BC_SIG_LOCK;
bc_vec_npop(&p->stack, i);
bc_vec_npop(&p->tail_calls, i);
+ BC_SIG_UNLOCK;
}
}
@@ -2311,9 +2332,9 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code,
// Parse.
bc_parse_text(&vm.read_prs, str, false);
- vm.expr(&vm.read_prs, BC_PARSE_NOCALL);
BC_SIG_LOCK;
+ vm.expr(&vm.read_prs, BC_PARSE_NOCALL);
BC_UNSETJMP;
@@ -2329,6 +2350,8 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code,
ip.len = p->results.len;
ip.func = fidx;
+ BC_SIG_LOCK;
+
// Pop the operand.
bc_vec_pop(&p->results);
@@ -2352,6 +2375,8 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code,
// Push the new function onto the execution stack and return.
bc_vec_push(&p->stack, &ip);
+ BC_SIG_UNLOCK;
+
return;
err:
@@ -2678,7 +2703,9 @@ void bc_program_exec(BcProgram *p) {
code = func->code.v;
// Ensure the pointers are correct.
+ BC_SIG_LOCK;
bc_program_setVecs(p, func);
+ BC_SIG_UNLOCK;
#if !BC_HAS_COMPUTED_GOTO
@@ -2759,10 +2786,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
+ BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
+ BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}
@@ -2792,10 +2821,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
+ BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
+ BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}
@@ -2824,10 +2855,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
+ BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
+ BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}
@@ -2909,10 +2942,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
+ BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
+ BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}
@@ -3086,10 +3121,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
+ BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
+ BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}
@@ -3103,10 +3140,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
+ BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
+ BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}
@@ -3179,10 +3218,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
+ BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
+ BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}