2 * support for dynamic binding from C
3 * See the "Chapter 9: Specials" of the SBCL Internals Manual.
7 * This software is part of the SBCL system. See the README file for
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.
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
);
44 lose("Oops! Static symbol missing from *KNOWN-TLS-SYMBOLS*");
45 binding
->value
= SymbolTlValue(symbol
, thread
);
48 binding
->symbol
= symbol
;
49 binding
->value
= SymbolTlValue(symbol
, thread
);
51 SetTlSymbolValue(symbol
, value
, thread
);
57 struct thread
*thread
=(struct thread
*)th
;
58 struct binding
*binding
;
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
]
71 SetSymbolValue(symbol
, binding
->value
, thread
);
77 set_binding_stack_pointer(thread
,binding
);
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
);
88 while (target
< binding
) {
91 symbol
= binding
->symbol
;
93 if (symbol
!= UNBOUND_MARKER_WIDETAG
) {
94 #ifdef LISP_FEATURE_SB_THREAD
95 ((union per_thread_data
*)thread
)->dynamic_values
[(symbol
) >> WORD_SHIFT
]
98 SetSymbolValue(symbol
, binding
->value
, thread
);
105 set_binding_stack_pointer(thread
,binding
);