-/* Copyright (C) 2001, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2009, 2010, 2011 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
#include <string.h>
#include "_scm.h"
-#include "vm-bootstrap.h"
+#include "threads.h"
#include "instructions.h"
+
struct scm_instruction {
enum scm_opcode opcode; /* opcode */
const char *name; /* instruction name */
} while (0)
+static scm_i_pthread_mutex_t itable_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER;
+
+
static struct scm_instruction*
fetch_instruction_table ()
{
static struct scm_instruction *table = NULL;
+ scm_i_pthread_mutex_lock (&itable_lock);
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);
#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_BOOL_F;
}
}
+ scm_i_pthread_mutex_unlock (&itable_lock);
+
return table;
}
struct scm_instruction *table = fetch_instruction_table ();
SCM op;
- 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++)
+ if (SCM_UNLIKELY (scm_is_false (instructions_by_name)))
+ {
+ unsigned int i;
+
+ instructions_by_name =
+ 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);
if (SCM_I_INUMP (op))
return &table[SCM_I_INUM (op)];
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);
"")
#define FUNC_NAME s_scm_instruction_p
{
- return SCM_BOOL (scm_lookup_instruction_by_name (obj));
+ return scm_from_bool (scm_lookup_instruction_by_name (obj) != NULL);
}
#undef FUNC_NAME
"")
#define FUNC_NAME s_scm_opcode_to_instruction
{
- int opcode;
+ scm_t_signed_bits opcode;
SCM ret = SCM_BOOL_F;
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))
void
scm_bootstrap_instructions (void)
{
- scm_c_register_extension ("libguile", "scm_init_instructions",
+ scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
+ "scm_init_instructions",
(scm_t_extension_init_func)scm_init_instructions,
NULL);
}
void
scm_init_instructions (void)
{
- scm_bootstrap_vm ();
-
#ifndef SCM_MAGIC_SNARFER
#include "libguile/instructions.x"
#endif