mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
fix race in which some instruction name symbols could go unmarked
* libguile/instructions.c: In loops, replace scm_op_last with SCM_VM_NUM_INSTRUCTIONS. (fetch_instruction_table): Protect the instruction symbols from collection. Before they were only marked by the name->opcode hash table, leading to races in which they could be collected. (scm_lookup_instruction_by_name): Protect the hash table earlier, as it's not actually a stack variable, since it's static.
This commit is contained in:
parent
cec1d4e33f
commit
ad47e35939
2 changed files with 9 additions and 9 deletions
|
@ -53,7 +53,7 @@ fetch_instruction_table ()
|
|||
|
||||
if (SCM_UNLIKELY (!table))
|
||||
{
|
||||
size_t bytes = scm_op_last * sizeof(struct scm_instruction);
|
||||
size_t bytes = SCM_VM_NUM_INSTRUCTIONS * sizeof(struct scm_instruction);
|
||||
int i;
|
||||
table = malloc (bytes);
|
||||
memset (table, 0, bytes);
|
||||
|
@ -63,11 +63,12 @@ fetch_instruction_table ()
|
|||
#include <libguile/vm-i-scheme.i>
|
||||
#include <libguile/vm-i-loader.i>
|
||||
#undef VM_INSTRUCTION_TO_TABLE
|
||||
for (i = 0; i < scm_op_last; i++)
|
||||
for (i = 0; i < SCM_VM_NUM_INSTRUCTIONS; i++)
|
||||
{
|
||||
table[i].opcode = i;
|
||||
if (table[i].name)
|
||||
table[i].symname = scm_from_locale_symbol (table[i].name);
|
||||
table[i].symname =
|
||||
scm_permanent_object (scm_from_locale_symbol (table[i].name));
|
||||
else
|
||||
table[i].symname = SCM_BOOL_F;
|
||||
}
|
||||
|
@ -85,12 +86,12 @@ scm_lookup_instruction_by_name (SCM name)
|
|||
if (SCM_UNLIKELY (SCM_FALSEP (instructions_by_name)))
|
||||
{
|
||||
int i;
|
||||
instructions_by_name = scm_make_hash_table (SCM_I_MAKINUM (scm_op_last));
|
||||
for (i = 0; i < scm_op_last; i++)
|
||||
instructions_by_name = scm_permanent_object
|
||||
(scm_make_hash_table (SCM_I_MAKINUM (SCM_VM_NUM_INSTRUCTIONS)));
|
||||
for (i = 0; i < SCM_VM_NUM_INSTRUCTIONS; i++)
|
||||
if (scm_is_true (table[i].symname))
|
||||
scm_hashq_set_x (instructions_by_name, table[i].symname,
|
||||
SCM_I_MAKINUM (i));
|
||||
instructions_by_name = scm_permanent_object (instructions_by_name);
|
||||
}
|
||||
|
||||
op = scm_hashq_ref (instructions_by_name, name, SCM_UNDEFINED);
|
||||
|
@ -111,7 +112,7 @@ SCM_DEFINE (scm_instruction_list, "instruction-list", 0, 0, 0,
|
|||
SCM list = SCM_EOL;
|
||||
int i;
|
||||
struct scm_instruction *ip = fetch_instruction_table ();
|
||||
for (i = 0; i < scm_op_last; i++)
|
||||
for (i = 0; i < SCM_VM_NUM_INSTRUCTIONS; i++)
|
||||
if (ip[i].name)
|
||||
list = scm_cons (ip[i].symname, list);
|
||||
return scm_reverse_x (list, SCM_EOL);
|
||||
|
@ -182,7 +183,7 @@ SCM_DEFINE (scm_opcode_to_instruction, "opcode->instruction", 1, 0, 0,
|
|||
SCM_MAKE_VALIDATE (1, op, I_INUMP);
|
||||
opcode = SCM_I_INUM (op);
|
||||
|
||||
if (opcode < scm_op_last)
|
||||
if (opcode >= 0 && opcode < SCM_VM_NUM_INSTRUCTIONS)
|
||||
ret = fetch_instruction_table ()[opcode].symname;
|
||||
|
||||
if (scm_is_false (ret))
|
||||
|
|
|
@ -31,7 +31,6 @@ enum scm_opcode {
|
|||
#include <libguile/vm-i-scheme.i>
|
||||
#include <libguile/vm-i-loader.i>
|
||||
#undef VM_INSTRUCTION_TO_OPCODE
|
||||
scm_op_last = SCM_VM_NUM_INSTRUCTIONS
|
||||
};
|
||||
|
||||
SCM_API SCM scm_instruction_list (void);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue