mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-14 15:40:19 +02:00
Fix thread-unsafe lazy initializations.
* libguile/backtrace.c (print_exception_var): New static variable. (init_print_exception_var): New static function. (scm_print_exception): Remove thread-unsafe lazy initialization. Call 'init_print_exception_var' using 'scm_i_pthread_once'. Use 'print_exception_var'. * libguile/continuations.c (call_cc): New static variable. (init_call_cc): New static function. (scm_i_call_with_current_continuation): Remove thread-unsafe lazy initialization. Call 'init_call_cc' using 'scm_i_pthread_once'. * libguile/debug.c (local_eval_var): New static variable. (init_local_eval_var): New static function. (scm_local_eval): Remove lazy initialization using mutexes. Call 'init_local_eval_var' using 'scm_i_pthread_once'. Use 'scm_variable_ref' instead of 'SCM_VARIABLE_REF'. * libguile/eval.c (map_var, for_each_var): New static variables. (init_map_var, init_for_each_var): New static functions. (scm_map, scm_for_each): Remove thread-unsafe lazy initializations. Call 'init_map_var' (or 'init_for_each_var') using 'scm_i_pthread_once'. Use 'map_var' (or 'for_each_var'). * libguile/frames.c (frame_arguments_var): New static variable. (init_frame_arguments_var): New static function. (scm_frame_arguments): Remove thread-unsafe lazy initialization. Call 'init_frame_arguments_var' using 'scm_i_pthread_once'. Use 'frame_arguments_var'. Use 'scm_variable_ref' instead of 'SCM_VARIABLE_REF'. * libguile/goops.c (delayed_compile_var): New static variable. (init_delayed_compile_var): New static function. (make_dispatch_procedure): Remove thread-unsafe lazy initialization. Call 'init_delayed_compile_var' using 'scm_i_pthread_once'. Use 'delayed_compile_var'. Use 'scm_variable_ref' instead of 'SCM_VARIABLE_REF'. * libguile/instructions.c (instructions_by_name): New static variable. (init_instructions_by_name): New static function. (scm_lookup_instruction_by_name): Remove thread-unsafe lazy initialization. Call 'init_instructions_by_name' using 'scm_i_pthread_once'. * libguile/ports.c (current_warning_port_var) (current_warning_port_once): New static variables. (init_current_warning_port_var): New static function. (scm_current_warning_port): Remove lazy initialization using mutexes. Call 'init_current_warning_port_var' using 'scm_i_pthread_once'. Use 'current_warning_port_var'. (scm_set_current_warning_port): Remove thread-unsafe lazy initialization. Call 'init_current_warning_port_var' using 'scm_i_pthread_once'. Use 'current_warning_port_var'. * libguile/strings.c (null_stringbuf): New static variable. (init_null_stringbuf): New static function. (scm_i_make_string): Remove thread-unsafe lazy initialization. Call 'init_null_stringbuf' using 'scm_i_pthread_once'. * libguile/strports.c (eval_string_var, k_module): New static variables. (init_eval_string_var_and_k_module): New static function. (scm_eval_string_in_module): Remove lazy initialization using mutexes. Call 'init_eval_string_var_and_k_module' using 'scm_i_pthread_once'. Use 'eval_string_var'. * libguile/throw.c (CACHE_VAR): Remove incorrect macro. (catch_var, throw_var, with_throw_handler_var): New static variables. (scm_catch, scm_catch_with_pre_unwind_handler): Remove thread-unsafe lazy initialization. Use 'catch_var'. (init_with_throw_handler_var): New static function. (scm_with_throw_handler): Remove thread-unsafe lazy initialization. Call 'init_with_throw_handler_var' using 'scm_i_pthread_once'. Use 'with_throw_handler_var'. (scm_throw): Remove thread-unsafe lazy initialization. Use 'throw_var'. (scm_init_throw): Initialize 'catch_var' and 'throw_var'.
This commit is contained in:
parent
f6ddf827f8
commit
60617d819d
11 changed files with 161 additions and 117 deletions
|
@ -67,24 +67,30 @@ boot_print_exception (SCM port, SCM frame, SCM key, SCM args)
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
static SCM print_exception_var;
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_print_exception_var (void)
|
||||||
|
{
|
||||||
|
print_exception_var
|
||||||
|
= scm_module_variable (scm_the_root_module (),
|
||||||
|
scm_from_latin1_symbol ("print-exception"));
|
||||||
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_print_exception (SCM port, SCM frame, SCM key, SCM args)
|
scm_print_exception (SCM port, SCM frame, SCM key, SCM args)
|
||||||
#define FUNC_NAME "print-exception"
|
#define FUNC_NAME "print-exception"
|
||||||
{
|
{
|
||||||
static SCM print_exception = SCM_BOOL_F;
|
static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
|
||||||
|
scm_i_pthread_once (&once, init_print_exception_var);
|
||||||
|
|
||||||
SCM_VALIDATE_OPOUTPORT (1, port);
|
SCM_VALIDATE_OPOUTPORT (1, port);
|
||||||
if (scm_is_true (frame))
|
if (scm_is_true (frame))
|
||||||
SCM_VALIDATE_FRAME (2, frame);
|
SCM_VALIDATE_FRAME (2, frame);
|
||||||
SCM_VALIDATE_SYMBOL (3, key);
|
SCM_VALIDATE_SYMBOL (3, key);
|
||||||
SCM_VALIDATE_LIST (4, args);
|
SCM_VALIDATE_LIST (4, args);
|
||||||
|
|
||||||
if (scm_is_false (print_exception))
|
|
||||||
print_exception =
|
|
||||||
scm_module_variable (scm_the_root_module (),
|
|
||||||
scm_from_latin1_symbol ("print-exception"));
|
|
||||||
|
|
||||||
return scm_call_4 (scm_variable_ref (print_exception),
|
return scm_call_4 (scm_variable_ref (print_exception_var),
|
||||||
port, frame, key, args);
|
port, frame, key, args);
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
|
@ -236,14 +236,20 @@ scm_i_make_continuation (int *first, SCM vm, SCM vm_cont)
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
static SCM call_cc;
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_call_cc (void)
|
||||||
|
{
|
||||||
|
call_cc = scm_make_program (call_cc_objcode, SCM_BOOL_F, SCM_BOOL_F);
|
||||||
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_i_call_with_current_continuation (SCM proc)
|
scm_i_call_with_current_continuation (SCM proc)
|
||||||
{
|
{
|
||||||
static SCM call_cc = SCM_BOOL_F;
|
static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
|
||||||
|
scm_i_pthread_once (&once, init_call_cc);
|
||||||
|
|
||||||
if (scm_is_false (call_cc))
|
|
||||||
call_cc = scm_make_program (call_cc_objcode, SCM_BOOL_F, SCM_BOOL_F);
|
|
||||||
|
|
||||||
return scm_call_1 (call_cc, proc);
|
return scm_call_1 (call_cc, proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -208,19 +208,21 @@ SCM_DEFINE (scm_debug_hang, "debug-hang", 0, 1, 0,
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static SCM local_eval_var;
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_local_eval_var (void)
|
||||||
|
{
|
||||||
|
local_eval_var = scm_c_public_variable ("ice-9 local-eval", "local-eval");
|
||||||
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_local_eval (SCM exp, SCM env)
|
scm_local_eval (SCM exp, SCM env)
|
||||||
{
|
{
|
||||||
static SCM local_eval_var = SCM_UNDEFINED;
|
static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
|
||||||
static scm_i_pthread_mutex_t local_eval_var_mutex
|
scm_i_pthread_once (&once, init_local_eval_var);
|
||||||
= SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
scm_i_scm_pthread_mutex_lock (&local_eval_var_mutex);
|
return scm_call_2 (scm_variable_ref (local_eval_var), exp, env);
|
||||||
if (SCM_UNBNDP (local_eval_var))
|
|
||||||
local_eval_var = scm_c_public_variable ("ice-9 local-eval", "local-eval");
|
|
||||||
scm_i_pthread_mutex_unlock (&local_eval_var_mutex);
|
|
||||||
|
|
||||||
return scm_call_2 (SCM_VARIABLE_REF (local_eval_var), exp, env);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -642,30 +642,37 @@ SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
static SCM map_var, for_each_var;
|
||||||
|
|
||||||
|
static void init_map_var (void)
|
||||||
|
{
|
||||||
|
map_var = scm_private_variable (scm_the_root_module (),
|
||||||
|
scm_from_latin1_symbol ("map"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_for_each_var (void)
|
||||||
|
{
|
||||||
|
for_each_var = scm_private_variable (scm_the_root_module (),
|
||||||
|
scm_from_latin1_symbol ("for-each"));
|
||||||
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_map (SCM proc, SCM arg1, SCM args)
|
scm_map (SCM proc, SCM arg1, SCM args)
|
||||||
{
|
{
|
||||||
static SCM var = SCM_BOOL_F;
|
static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
|
||||||
|
scm_i_pthread_once (&once, init_map_var);
|
||||||
|
|
||||||
if (scm_is_false (var))
|
return scm_apply (scm_variable_ref (map_var),
|
||||||
var = scm_private_variable (scm_the_root_module (),
|
|
||||||
scm_from_latin1_symbol ("map"));
|
|
||||||
|
|
||||||
return scm_apply (scm_variable_ref (var),
|
|
||||||
scm_cons (proc, scm_cons (arg1, args)), SCM_EOL);
|
scm_cons (proc, scm_cons (arg1, args)), SCM_EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_for_each (SCM proc, SCM arg1, SCM args)
|
scm_for_each (SCM proc, SCM arg1, SCM args)
|
||||||
{
|
{
|
||||||
static SCM var = SCM_BOOL_F;
|
static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
|
||||||
|
scm_i_pthread_once (&once, init_for_each_var);
|
||||||
|
|
||||||
if (scm_is_false (var))
|
return scm_apply (scm_variable_ref (for_each_var),
|
||||||
var = scm_private_variable (scm_the_root_module (),
|
|
||||||
scm_from_latin1_symbol ("for-each"));
|
|
||||||
|
|
||||||
return scm_apply (scm_variable_ref (var),
|
|
||||||
scm_cons (proc, scm_cons (arg1, args)), SCM_EOL);
|
scm_cons (proc, scm_cons (arg1, args)), SCM_EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,20 +82,26 @@ SCM_DEFINE (scm_frame_procedure, "frame-procedure", 1, 0, 0,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
static SCM frame_arguments_var;
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_frame_arguments_var (void)
|
||||||
|
{
|
||||||
|
frame_arguments_var
|
||||||
|
= scm_c_private_lookup ("system vm frame", "frame-arguments");
|
||||||
|
}
|
||||||
|
|
||||||
SCM_DEFINE (scm_frame_arguments, "frame-arguments", 1, 0, 0,
|
SCM_DEFINE (scm_frame_arguments, "frame-arguments", 1, 0, 0,
|
||||||
(SCM frame),
|
(SCM frame),
|
||||||
"")
|
"")
|
||||||
#define FUNC_NAME s_scm_frame_arguments
|
#define FUNC_NAME s_scm_frame_arguments
|
||||||
{
|
{
|
||||||
static SCM var = SCM_BOOL_F;
|
static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
|
||||||
|
scm_i_pthread_once (&once, init_frame_arguments_var);
|
||||||
|
|
||||||
SCM_VALIDATE_VM_FRAME (1, frame);
|
SCM_VALIDATE_VM_FRAME (1, frame);
|
||||||
|
|
||||||
if (scm_is_false (var))
|
return scm_call_1 (scm_variable_ref (frame_arguments_var), frame);
|
||||||
var = scm_c_module_lookup (scm_c_resolve_module ("system vm frame"),
|
|
||||||
"frame-arguments");
|
|
||||||
|
|
||||||
return scm_call_1 (SCM_VARIABLE_REF (var), frame);
|
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
|
@ -1763,15 +1763,22 @@ scm_call_generic_3 (SCM gf, SCM a1, SCM a2, SCM a3)
|
||||||
return scm_call_3 (SCM_STRUCT_PROCEDURE (gf), a1, a2, a3);
|
return scm_call_3 (SCM_STRUCT_PROCEDURE (gf), a1, a2, a3);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM_SYMBOL (sym_delayed_compile, "delayed-compile");
|
static SCM delayed_compile_var;
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_delayed_compile_var (void)
|
||||||
|
{
|
||||||
|
delayed_compile_var
|
||||||
|
= scm_c_private_lookup ("oop goops dispatch", "delayed-compile");
|
||||||
|
}
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
make_dispatch_procedure (SCM gf)
|
make_dispatch_procedure (SCM gf)
|
||||||
{
|
{
|
||||||
static SCM var = SCM_BOOL_F;
|
static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
|
||||||
if (scm_is_false (var))
|
scm_i_pthread_once (&once, init_delayed_compile_var);
|
||||||
var = scm_module_variable (scm_c_resolve_module ("oop goops dispatch"),
|
|
||||||
sym_delayed_compile);
|
return scm_call_1 (scm_variable_ref (delayed_compile_var), gf);
|
||||||
return scm_call_1 (SCM_VARIABLE_REF (var), gf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -82,25 +82,31 @@ fetch_instruction_table ()
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SCM instructions_by_name;
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_instructions_by_name (void)
|
||||||
|
{
|
||||||
|
struct scm_instruction *table = fetch_instruction_table ();
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
static struct scm_instruction *
|
static struct scm_instruction *
|
||||||
scm_lookup_instruction_by_name (SCM name)
|
scm_lookup_instruction_by_name (SCM name)
|
||||||
{
|
{
|
||||||
static SCM instructions_by_name = SCM_BOOL_F;
|
static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
|
||||||
struct scm_instruction *table = fetch_instruction_table ();
|
struct scm_instruction *table = fetch_instruction_table ();
|
||||||
SCM op;
|
SCM op;
|
||||||
|
|
||||||
if (SCM_UNLIKELY (scm_is_false (instructions_by_name)))
|
scm_i_pthread_once (&once, init_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));
|
|
||||||
}
|
|
||||||
|
|
||||||
op = scm_hashq_ref (instructions_by_name, name, SCM_UNDEFINED);
|
op = scm_hashq_ref (instructions_by_name, name, SCM_UNDEFINED);
|
||||||
if (SCM_I_INUMP (op))
|
if (SCM_I_INUMP (op))
|
||||||
|
|
|
@ -454,19 +454,22 @@ SCM_DEFINE (scm_current_error_port, "current-error-port", 0, 0, 0,
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
static SCM current_warning_port_var;
|
||||||
|
static scm_i_pthread_once_t current_warning_port_once = SCM_I_PTHREAD_ONCE_INIT;
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_current_warning_port_var (void)
|
||||||
|
{
|
||||||
|
current_warning_port_var
|
||||||
|
= scm_c_private_variable ("guile", "current-warning-port");
|
||||||
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_current_warning_port (void)
|
scm_current_warning_port (void)
|
||||||
{
|
{
|
||||||
static SCM cwp_var = SCM_UNDEFINED;
|
scm_i_pthread_once (¤t_warning_port_once,
|
||||||
static scm_i_pthread_mutex_t cwp_var_mutex
|
init_current_warning_port_var);
|
||||||
= SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
return scm_call_0 (scm_variable_ref (current_warning_port_var));
|
||||||
|
|
||||||
scm_i_scm_pthread_mutex_lock (&cwp_var_mutex);
|
|
||||||
if (SCM_UNBNDP (cwp_var))
|
|
||||||
cwp_var = scm_c_private_variable ("guile", "current-warning-port");
|
|
||||||
scm_i_pthread_mutex_unlock (&cwp_var_mutex);
|
|
||||||
|
|
||||||
return scm_call_0 (scm_variable_ref (cwp_var));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM_DEFINE (scm_current_load_port, "current-load-port", 0, 0, 0,
|
SCM_DEFINE (scm_current_load_port, "current-load-port", 0, 0, 0,
|
||||||
|
@ -527,12 +530,9 @@ SCM_DEFINE (scm_set_current_error_port, "set-current-error-port", 1, 0, 0,
|
||||||
SCM
|
SCM
|
||||||
scm_set_current_warning_port (SCM port)
|
scm_set_current_warning_port (SCM port)
|
||||||
{
|
{
|
||||||
static SCM cwp_var = SCM_BOOL_F;
|
scm_i_pthread_once (¤t_warning_port_once,
|
||||||
|
init_current_warning_port_var);
|
||||||
if (scm_is_false (cwp_var))
|
return scm_call_1 (scm_variable_ref (current_warning_port_var), port);
|
||||||
cwp_var = scm_c_private_lookup ("guile", "current-warning-port");
|
|
||||||
|
|
||||||
return scm_call_1 (scm_variable_ref (cwp_var), port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -260,6 +260,15 @@ scm_i_pthread_mutex_t stringbuf_write_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
SCM scm_nullstr;
|
SCM scm_nullstr;
|
||||||
|
|
||||||
|
static SCM null_stringbuf;
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_null_stringbuf (void)
|
||||||
|
{
|
||||||
|
null_stringbuf = make_stringbuf (0);
|
||||||
|
SET_STRINGBUF_SHARED (null_stringbuf);
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a scheme string with space for LEN 8-bit Latin-1-encoded
|
/* Create a scheme string with space for LEN 8-bit Latin-1-encoded
|
||||||
characters. CHARSP, if not NULL, will be set to location of the
|
characters. CHARSP, if not NULL, will be set to location of the
|
||||||
char array. If READ_ONLY_P, the returned string is read-only;
|
char array. If READ_ONLY_P, the returned string is read-only;
|
||||||
|
@ -267,17 +276,13 @@ SCM scm_nullstr;
|
||||||
SCM
|
SCM
|
||||||
scm_i_make_string (size_t len, char **charsp, int read_only_p)
|
scm_i_make_string (size_t len, char **charsp, int read_only_p)
|
||||||
{
|
{
|
||||||
static SCM null_stringbuf = SCM_BOOL_F;
|
|
||||||
SCM buf;
|
SCM buf;
|
||||||
SCM res;
|
SCM res;
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
if (SCM_UNLIKELY (scm_is_false (null_stringbuf)))
|
static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
|
||||||
{
|
scm_i_pthread_once (&once, init_null_stringbuf);
|
||||||
null_stringbuf = make_stringbuf (0);
|
|
||||||
SET_STRINGBUF_SHARED (null_stringbuf);
|
|
||||||
}
|
|
||||||
buf = null_stringbuf;
|
buf = null_stringbuf;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -523,6 +523,16 @@ scm_c_eval_string_in_module (const char *expr, SCM module)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static SCM eval_string_var;
|
||||||
|
static SCM k_module;
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_eval_string_var_and_k_module (void)
|
||||||
|
{
|
||||||
|
eval_string_var = scm_c_public_variable ("ice-9 eval-string", "eval-string");
|
||||||
|
k_module = scm_from_locale_keyword ("module");
|
||||||
|
}
|
||||||
|
|
||||||
SCM_DEFINE (scm_eval_string_in_module, "eval-string", 1, 1, 0,
|
SCM_DEFINE (scm_eval_string_in_module, "eval-string", 1, 1, 0,
|
||||||
(SCM string, SCM module),
|
(SCM string, SCM module),
|
||||||
"Evaluate @var{string} as the text representation of a Scheme\n"
|
"Evaluate @var{string} as the text representation of a Scheme\n"
|
||||||
|
@ -534,23 +544,16 @@ SCM_DEFINE (scm_eval_string_in_module, "eval-string", 1, 1, 0,
|
||||||
"procedure returns.")
|
"procedure returns.")
|
||||||
#define FUNC_NAME s_scm_eval_string_in_module
|
#define FUNC_NAME s_scm_eval_string_in_module
|
||||||
{
|
{
|
||||||
static SCM eval_string = SCM_UNDEFINED, k_module = SCM_UNDEFINED;
|
static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
|
||||||
static scm_i_pthread_mutex_t init_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
scm_i_pthread_once (&once, init_eval_string_var_and_k_module);
|
||||||
|
|
||||||
scm_i_scm_pthread_mutex_lock (&init_mutex);
|
|
||||||
if (SCM_UNBNDP (eval_string))
|
|
||||||
{
|
|
||||||
eval_string = scm_c_public_variable ("ice-9 eval-string", "eval-string");
|
|
||||||
k_module = scm_from_locale_keyword ("module");
|
|
||||||
}
|
|
||||||
scm_i_pthread_mutex_unlock (&init_mutex);
|
|
||||||
|
|
||||||
if (SCM_UNBNDP (module))
|
if (SCM_UNBNDP (module))
|
||||||
module = scm_current_module ();
|
module = scm_current_module ();
|
||||||
else
|
else
|
||||||
SCM_VALIDATE_MODULE (2, module);
|
SCM_VALIDATE_MODULE (2, module);
|
||||||
|
|
||||||
return scm_call_3 (scm_variable_ref (eval_string), string, k_module, module);
|
return scm_call_3 (scm_variable_ref (eval_string_var),
|
||||||
|
string, k_module, module);
|
||||||
}
|
}
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
|
@ -53,24 +53,14 @@
|
||||||
baggage. */
|
baggage. */
|
||||||
|
|
||||||
|
|
||||||
#define CACHE_VAR(var,name) \
|
|
||||||
static SCM var = SCM_BOOL_F; \
|
|
||||||
if (scm_is_false (var)) \
|
|
||||||
{ \
|
|
||||||
var = scm_module_variable (scm_the_root_module (), \
|
|
||||||
scm_from_latin1_symbol (name)); \
|
|
||||||
if (scm_is_false (var)) \
|
|
||||||
abort (); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static SCM catch_var, throw_var, with_throw_handler_var;
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_catch (SCM key, SCM thunk, SCM handler)
|
scm_catch (SCM key, SCM thunk, SCM handler)
|
||||||
{
|
{
|
||||||
CACHE_VAR (var, "catch");
|
return scm_call_3 (scm_variable_ref (catch_var), key, thunk, handler);
|
||||||
|
|
||||||
return scm_call_3 (scm_variable_ref (var), key, thunk, handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
|
@ -80,28 +70,32 @@ scm_catch_with_pre_unwind_handler (SCM key, SCM thunk, SCM handler,
|
||||||
if (SCM_UNBNDP (pre_unwind_handler))
|
if (SCM_UNBNDP (pre_unwind_handler))
|
||||||
return scm_catch (key, thunk, handler);
|
return scm_catch (key, thunk, handler);
|
||||||
else
|
else
|
||||||
{
|
return scm_call_4 (scm_variable_ref (catch_var), key, thunk, handler,
|
||||||
CACHE_VAR (var, "catch");
|
pre_unwind_handler);
|
||||||
|
}
|
||||||
return scm_call_4 (scm_variable_ref (var), key, thunk, handler,
|
|
||||||
pre_unwind_handler);
|
static void
|
||||||
}
|
init_with_throw_handler_var (void)
|
||||||
|
{
|
||||||
|
with_throw_handler_var
|
||||||
|
= scm_module_variable (scm_the_root_module (),
|
||||||
|
scm_from_latin1_symbol ("with-throw-handler"));
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_with_throw_handler (SCM key, SCM thunk, SCM handler)
|
scm_with_throw_handler (SCM key, SCM thunk, SCM handler)
|
||||||
{
|
{
|
||||||
CACHE_VAR (var, "with-throw-handler");
|
static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
|
||||||
|
scm_i_pthread_once (&once, init_with_throw_handler_var);
|
||||||
|
|
||||||
return scm_call_3 (scm_variable_ref (var), key, thunk, handler);
|
return scm_call_3 (scm_variable_ref (with_throw_handler_var),
|
||||||
|
key, thunk, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_throw (SCM key, SCM args)
|
scm_throw (SCM key, SCM args)
|
||||||
{
|
{
|
||||||
CACHE_VAR (var, "throw");
|
return scm_apply_1 (scm_variable_ref (throw_var), key, args);
|
||||||
|
|
||||||
return scm_apply_1 (scm_variable_ref (var), key, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -534,8 +528,10 @@ scm_init_throw ()
|
||||||
tc16_catch_closure = scm_make_smob_type ("catch-closure", 0);
|
tc16_catch_closure = scm_make_smob_type ("catch-closure", 0);
|
||||||
scm_set_smob_apply (tc16_catch_closure, apply_catch_closure, 0, 0, 1);
|
scm_set_smob_apply (tc16_catch_closure, apply_catch_closure, 0, 0, 1);
|
||||||
|
|
||||||
scm_c_define ("catch", scm_c_make_gsubr ("catch", 3, 1, 0, pre_init_catch));
|
catch_var = scm_c_define ("catch", scm_c_make_gsubr ("catch", 3, 1, 0,
|
||||||
scm_c_define ("throw", scm_c_make_gsubr ("throw", 1, 0, 1, pre_init_throw));
|
pre_init_catch));
|
||||||
|
throw_var = scm_c_define ("throw", scm_c_make_gsubr ("throw", 1, 0, 1,
|
||||||
|
pre_init_throw));
|
||||||
|
|
||||||
#include "libguile/throw.x"
|
#include "libguile/throw.x"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue