Add a declaration
[sbcl.git] / src / runtime / dynbind.c
blob554a56596c5d6d66865f1adc91718dd88ee2dcb7
1 /*
2 * support for dynamic binding from C
3 * See the "Chapter 9: Specials" of the SBCL Internals Manual.
4 */
6 /*
7 * This software is part of the SBCL system. See the README file for
8 * more information.
10 * This software is derived from the CMU CL system, which was
11 * written at Carnegie Mellon University and released into the
12 * public domain. The software is in the public domain and is
13 * provided with absolutely no warranty. See the COPYING and CREDITS
14 * files for more information.
17 #include <stdio.h>
18 #include <stdlib.h>
20 #include "sbcl.h"
21 #include "runtime.h"
22 #include "globals.h"
23 #include "dynbind.h"
24 #include "thread.h"
25 #include "genesis/symbol.h"
26 #include "genesis/binding.h"
28 /* Specially bind SYMBOL to VALUE. In a multithreaded build, SYMBOL must already
29 have been assigned a thread-local storage index. See *KNOWN-TLS-SYMBOLS* in
30 compiler/generic/genesis for the symbols whose indices are pre-assigned. */
31 void bind_variable(lispobj symbol, lispobj value, void *th)
33 struct binding *binding;
34 struct thread *thread=(struct thread *)th;
35 binding = (struct binding *)get_binding_stack_pointer(thread);
36 set_binding_stack_pointer(thread,binding+1);
37 #ifdef LISP_FEATURE_SB_THREAD
39 struct symbol *sym=(struct symbol *)native_pointer(symbol);
40 // We could provide a c-callable static Lisp function to assign TLS
41 // indices if anyone really needs dynamic binding of dynamic symbols.
42 binding->symbol = tls_index_of(sym);
43 if(!binding->symbol)
44 lose("Oops! Static symbol missing from *KNOWN-TLS-SYMBOLS*");
45 binding->value = SymbolTlValue(symbol, thread);
47 #else
48 binding->symbol = symbol;
49 binding->value = SymbolTlValue(symbol, thread);
50 #endif
51 SetTlSymbolValue(symbol, value, thread);
54 void
55 unbind(void *th)
57 struct thread *thread=(struct thread *)th;
58 struct binding *binding;
59 lispobj symbol;
61 binding = ((struct binding *)get_binding_stack_pointer(thread)) - 1;
63 /* On sb-thread, it's actually a tls-index */
64 symbol = binding->symbol;
66 #ifdef LISP_FEATURE_SB_THREAD
68 ((union per_thread_data *)thread)->dynamic_values[(symbol) >> WORD_SHIFT]
69 = binding->value;
70 #else
71 SetSymbolValue(symbol, binding->value, thread);
72 #endif
74 binding->symbol = 0;
75 binding->value = 0;
77 set_binding_stack_pointer(thread,binding);
80 void
81 unbind_to_here(lispobj *bsp,void *th)
83 struct thread *thread=(struct thread *)th;
84 struct binding *target = (struct binding *)bsp;
85 struct binding *binding = (struct binding *)get_binding_stack_pointer(thread);
86 lispobj symbol;
88 while (target < binding) {
89 binding--;
91 symbol = binding->symbol;
92 if (symbol) {
93 if (symbol != UNBOUND_MARKER_WIDETAG) {
94 #ifdef LISP_FEATURE_SB_THREAD
95 ((union per_thread_data *)thread)->dynamic_values[(symbol) >> WORD_SHIFT]
96 = binding->value;
97 #else
98 SetSymbolValue(symbol, binding->value, thread);
99 #endif
101 binding->symbol = 0;
102 binding->value = 0;
105 set_binding_stack_pointer(thread,binding);