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 #ifdef LISP_FEATURE_SB_THREAD
33 #define value_address(thing, thread) \
34 (lispobj*)(thing + (char*)((union per_thread_data *)thread)->dynamic_values)
35 void bind_tls_cell(unsigned symbol
, lispobj value
, void *th
)
37 #define value_address(thing, thread) &SYMBOL(thing)->value
38 void bind_variable(lispobj symbol
, lispobj value
, void *th
)
41 struct binding
*binding
;
42 __attribute__((unused
)) struct thread
*thread
= (struct thread
*)th
;
43 binding
= (struct binding
*)get_binding_stack_pointer(thread
);
44 set_binding_stack_pointer(thread
,binding
+1);
45 binding
->symbol
= symbol
;
46 lispobj
* where
= value_address(symbol
, thread
);
47 binding
->value
= *where
;
54 __attribute__((unused
)) struct thread
*thread
= (struct thread
*)th
;
55 struct binding
*binding
;
57 binding
= ((struct binding
*)get_binding_stack_pointer(thread
)) - 1;
59 /* On sb-thread, 'binding->symbol' is actually a tls-index */
60 *value_address(binding
->symbol
, thread
) = binding
->value
;
65 set_binding_stack_pointer(thread
,binding
);
69 unbind_to_here(lispobj
*bsp
,void *th
)
71 __attribute__((unused
)) struct thread
*thread
= (struct thread
*)th
;
72 struct binding
*target
= (struct binding
*)bsp
;
73 struct binding
*binding
= (struct binding
*)get_binding_stack_pointer(thread
);
76 while (target
< binding
) {
79 symbol
= binding
->symbol
;
81 if (symbol
!= UNBOUND_MARKER_WIDETAG
) {
82 *value_address(symbol
, thread
) = binding
->value
;
88 set_binding_stack_pointer(thread
,binding
);