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.
26 #include "genesis/symbol.h"
27 #include "genesis/binding.h"
29 /* Specially bind SYMBOL to VALUE. In a multithreaded build, SYMBOL must already
30 have been assigned a thread-local storage index. See *KNOWN-TLS-SYMBOLS* in
31 compiler/generic/genesis for the symbols whose indices are pre-assigned. */
32 void bind_variable(lispobj symbol
, lispobj value
, void *th
)
34 struct binding
*binding
;
35 struct thread
*thread
=(struct thread
*)th
;
36 binding
= (struct binding
*)get_binding_stack_pointer(thread
);
37 set_binding_stack_pointer(thread
,binding
+1);
38 #ifdef LISP_FEATURE_SB_THREAD
40 struct symbol
*sym
=(struct symbol
*)native_pointer(symbol
);
41 // We could provide a c-callable static Lisp function to assign TLS
42 // indices if anyone really needs dynamic binding of dynamic symbols.
43 binding
->symbol
= tls_index_of(sym
);
45 lose("Oops! Static symbol missing from *KNOWN-TLS-SYMBOLS*");
46 binding
->value
= SymbolTlValue(symbol
, thread
);
49 binding
->symbol
= symbol
;
50 binding
->value
= SymbolTlValue(symbol
, thread
);
52 SetTlSymbolValue(symbol
, value
, thread
);
58 struct thread
*thread
=(struct thread
*)th
;
59 struct binding
*binding
;
62 binding
= ((struct binding
*)get_binding_stack_pointer(thread
)) - 1;
64 /* On sb-thread, it's actually a tls-index */
65 symbol
= binding
->symbol
;
67 #ifdef LISP_FEATURE_SB_THREAD
69 ((union per_thread_data
*)thread
)->dynamic_values
[(symbol
) >> WORD_SHIFT
]
72 SetSymbolValue(symbol
, binding
->value
, thread
);
78 set_binding_stack_pointer(thread
,binding
);
82 unbind_to_here(lispobj
*bsp
,void *th
)
84 struct thread
*thread
=(struct thread
*)th
;
85 struct binding
*target
= (struct binding
*)bsp
;
86 struct binding
*binding
= (struct binding
*)get_binding_stack_pointer(thread
);
89 while (target
< binding
) {
92 symbol
= binding
->symbol
;
94 if (symbol
!= UNBOUND_MARKER_WIDETAG
) {
95 #ifdef LISP_FEATURE_SB_THREAD
96 ((union per_thread_data
*)thread
)->dynamic_values
[(symbol
) >> WORD_SHIFT
]
99 SetSymbolValue(symbol
, binding
->value
, thread
);
106 set_binding_stack_pointer(thread
,binding
);