xref: /freebsd/contrib/bc/include/library.h (revision a970610a3af63b3f4df5b69d91c6b4093a00ed8f)
150696a6eSStefan Eßer /*
250696a6eSStefan Eßer  * *****************************************************************************
350696a6eSStefan Eßer  *
450696a6eSStefan Eßer  * SPDX-License-Identifier: BSD-2-Clause
550696a6eSStefan Eßer  *
6*a970610aSStefan Eßer  * Copyright (c) 2018-2024 Gavin D. Howard and contributors.
750696a6eSStefan Eßer  *
850696a6eSStefan Eßer  * Redistribution and use in source and binary forms, with or without
950696a6eSStefan Eßer  * modification, are permitted provided that the following conditions are met:
1050696a6eSStefan Eßer  *
1150696a6eSStefan Eßer  * * Redistributions of source code must retain the above copyright notice, this
1250696a6eSStefan Eßer  *   list of conditions and the following disclaimer.
1350696a6eSStefan Eßer  *
1450696a6eSStefan Eßer  * * Redistributions in binary form must reproduce the above copyright notice,
1550696a6eSStefan Eßer  *   this list of conditions and the following disclaimer in the documentation
1650696a6eSStefan Eßer  *   and/or other materials provided with the distribution.
1750696a6eSStefan Eßer  *
1850696a6eSStefan Eßer  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1950696a6eSStefan Eßer  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2050696a6eSStefan Eßer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2150696a6eSStefan Eßer  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2250696a6eSStefan Eßer  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2350696a6eSStefan Eßer  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2450696a6eSStefan Eßer  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2550696a6eSStefan Eßer  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2650696a6eSStefan Eßer  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2750696a6eSStefan Eßer  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2850696a6eSStefan Eßer  * POSSIBILITY OF SUCH DAMAGE.
2950696a6eSStefan Eßer  *
3050696a6eSStefan Eßer  * *****************************************************************************
3150696a6eSStefan Eßer  *
3250696a6eSStefan Eßer  * The private header for the bc library.
3350696a6eSStefan Eßer  *
3450696a6eSStefan Eßer  */
3550696a6eSStefan Eßer 
3650696a6eSStefan Eßer #ifndef LIBBC_PRIVATE_H
3750696a6eSStefan Eßer #define LIBBC_PRIVATE_H
3850696a6eSStefan Eßer 
39d101cdd6SStefan Eßer #ifndef _WIN32
40d101cdd6SStefan Eßer 
41d101cdd6SStefan Eßer #include <pthread.h>
42d101cdd6SStefan Eßer 
43d101cdd6SStefan Eßer #endif // _WIN32
44d101cdd6SStefan Eßer 
4550696a6eSStefan Eßer #include <bcl.h>
4650696a6eSStefan Eßer 
4750696a6eSStefan Eßer #include <num.h>
48d101cdd6SStefan Eßer #include <vm.h>
4950696a6eSStefan Eßer 
50175a4d10SStefan Eßer #if BC_ENABLE_MEMCHECK
51175a4d10SStefan Eßer 
52175a4d10SStefan Eßer /**
53175a4d10SStefan Eßer  * A typedef for Valgrind builds. This is to add a generation index for error
54175a4d10SStefan Eßer  * checking.
55175a4d10SStefan Eßer  */
56175a4d10SStefan Eßer typedef struct BclNum
57175a4d10SStefan Eßer {
58175a4d10SStefan Eßer 	/// The number.
59175a4d10SStefan Eßer 	BcNum n;
60175a4d10SStefan Eßer 
61175a4d10SStefan Eßer 	/// The generation index.
62175a4d10SStefan Eßer 	size_t gen_idx;
63175a4d10SStefan Eßer 
64175a4d10SStefan Eßer } BclNum;
65175a4d10SStefan Eßer 
66175a4d10SStefan Eßer /**
67175a4d10SStefan Eßer  * Clears the generation byte in a BclNumber and returns the value.
68175a4d10SStefan Eßer  * @param n  The BclNumber.
69175a4d10SStefan Eßer  * @return   The value of the index.
70175a4d10SStefan Eßer  */
71175a4d10SStefan Eßer #define BCL_NO_GEN(n) \
72175a4d10SStefan Eßer 	((n).i & ~(((size_t) UCHAR_MAX) << ((sizeof(size_t) - 1) * CHAR_BIT)))
73175a4d10SStefan Eßer 
74175a4d10SStefan Eßer /**
75175a4d10SStefan Eßer  * Gets the generation index in a BclNumber.
76175a4d10SStefan Eßer  * @param n  The BclNumber.
77175a4d10SStefan Eßer  * @return   The generation index.
78175a4d10SStefan Eßer  */
79175a4d10SStefan Eßer #define BCL_GET_GEN(n) ((n).i >> ((sizeof(size_t) - 1) * CHAR_BIT))
80175a4d10SStefan Eßer 
81175a4d10SStefan Eßer /**
82175a4d10SStefan Eßer  * Turns a BclNumber into a BcNum.
83175a4d10SStefan Eßer  * @param c  The context.
84175a4d10SStefan Eßer  * @param n  The BclNumber.
85175a4d10SStefan Eßer  */
86175a4d10SStefan Eßer #define BCL_NUM(c, n) ((BclNum*) bc_vec_item(&(c)->nums, BCL_NO_GEN(n)))
87175a4d10SStefan Eßer 
88175a4d10SStefan Eßer /**
89175a4d10SStefan Eßer  * Clears the generation index top byte in the BclNumber.
90175a4d10SStefan Eßer  * @param n  The BclNumber.
91175a4d10SStefan Eßer  */
92175a4d10SStefan Eßer #define BCL_CLEAR_GEN(n)                                                       \
93175a4d10SStefan Eßer 	do                                                                         \
94175a4d10SStefan Eßer 	{                                                                          \
95175a4d10SStefan Eßer 		(n).i &= ~(((size_t) UCHAR_MAX) << ((sizeof(size_t) - 1) * CHAR_BIT)); \
96175a4d10SStefan Eßer 	}                                                                          \
97175a4d10SStefan Eßer 	while (0)
98175a4d10SStefan Eßer 
99175a4d10SStefan Eßer #define BCL_CHECK_NUM_GEN(c, bn)         \
100175a4d10SStefan Eßer 	do                                   \
101175a4d10SStefan Eßer 	{                                    \
102175a4d10SStefan Eßer 		size_t gen_ = BCL_GET_GEN(bn);   \
103175a4d10SStefan Eßer 		BclNum* ptr_ = BCL_NUM(c, bn);   \
104175a4d10SStefan Eßer 		if (BCL_NUM_ARRAY(ptr_) == NULL) \
105175a4d10SStefan Eßer 		{                                \
106175a4d10SStefan Eßer 			bcl_nonexistentNum();        \
107175a4d10SStefan Eßer 		}                                \
108175a4d10SStefan Eßer 		if (gen_ != ptr_->gen_idx)       \
109175a4d10SStefan Eßer 		{                                \
110175a4d10SStefan Eßer 			bcl_invalidGeneration();     \
111175a4d10SStefan Eßer 		}                                \
112175a4d10SStefan Eßer 	}                                    \
113175a4d10SStefan Eßer 	while (0)
114175a4d10SStefan Eßer 
115175a4d10SStefan Eßer #define BCL_CHECK_NUM_VALID(c, bn)    \
116175a4d10SStefan Eßer 	do                                \
117175a4d10SStefan Eßer 	{                                 \
118175a4d10SStefan Eßer 		size_t idx_ = BCL_NO_GEN(bn); \
119175a4d10SStefan Eßer 		if ((c)->nums.len <= idx_)    \
120175a4d10SStefan Eßer 		{                             \
121175a4d10SStefan Eßer 			bcl_numIdxOutOfRange();   \
122175a4d10SStefan Eßer 		}                             \
123175a4d10SStefan Eßer 		BCL_CHECK_NUM_GEN(c, bn);     \
124175a4d10SStefan Eßer 	}                                 \
125175a4d10SStefan Eßer 	while (0)
126175a4d10SStefan Eßer 
127175a4d10SStefan Eßer /**
128175a4d10SStefan Eßer  * Returns the limb array of the number.
129175a4d10SStefan Eßer  * @param bn  The number.
130175a4d10SStefan Eßer  * @return    The limb array.
131175a4d10SStefan Eßer  */
132175a4d10SStefan Eßer #define BCL_NUM_ARRAY(bn) ((bn)->n.num)
133175a4d10SStefan Eßer 
134175a4d10SStefan Eßer /**
135175a4d10SStefan Eßer  * Returns the limb array of the number for a non-pointer.
136175a4d10SStefan Eßer  * @param bn  The number.
137175a4d10SStefan Eßer  * @return    The limb array.
138175a4d10SStefan Eßer  */
139175a4d10SStefan Eßer #define BCL_NUM_ARRAY_NP(bn) ((bn).n.num)
140175a4d10SStefan Eßer 
141175a4d10SStefan Eßer /**
142175a4d10SStefan Eßer  * Returns the BcNum pointer.
143175a4d10SStefan Eßer  * @param bn  The number.
144175a4d10SStefan Eßer  * @return    The BcNum pointer.
145175a4d10SStefan Eßer  */
146175a4d10SStefan Eßer #define BCL_NUM_NUM(bn) (&(bn)->n)
147175a4d10SStefan Eßer 
148175a4d10SStefan Eßer /**
149175a4d10SStefan Eßer  * Returns the BcNum pointer for a non-pointer.
150175a4d10SStefan Eßer  * @param bn  The number.
151175a4d10SStefan Eßer  * @return    The BcNum pointer.
152175a4d10SStefan Eßer  */
153175a4d10SStefan Eßer #define BCL_NUM_NUM_NP(bn) (&(bn).n)
154175a4d10SStefan Eßer 
155175a4d10SStefan Eßer // These functions only abort. They exist to give developers some idea of what
156175a4d10SStefan Eßer // went wrong when bugs are found, if they look at the Valgrind stack trace.
157175a4d10SStefan Eßer 
158175a4d10SStefan Eßer BC_NORETURN void
159175a4d10SStefan Eßer bcl_invalidGeneration(void);
160175a4d10SStefan Eßer 
161175a4d10SStefan Eßer BC_NORETURN void
162175a4d10SStefan Eßer bcl_nonexistentNum(void);
163175a4d10SStefan Eßer 
164175a4d10SStefan Eßer BC_NORETURN void
165175a4d10SStefan Eßer bcl_numIdxOutOfRange(void);
166175a4d10SStefan Eßer 
167175a4d10SStefan Eßer #else // BC_ENABLE_MEMCHECK
168175a4d10SStefan Eßer 
169175a4d10SStefan Eßer /**
170175a4d10SStefan Eßer  * A typedef for non-Valgrind builds.
171175a4d10SStefan Eßer  */
172175a4d10SStefan Eßer typedef BcNum BclNum;
173175a4d10SStefan Eßer 
174175a4d10SStefan Eßer #define BCL_NO_GEN(n) ((n).i)
175175a4d10SStefan Eßer #define BCL_NUM(c, n) ((BclNum*) bc_vec_item(&(c)->nums, (n).i))
176175a4d10SStefan Eßer #define BCL_CLEAR_GEN(n) ((void) (n))
177175a4d10SStefan Eßer 
178175a4d10SStefan Eßer #define BCL_CHECK_NUM_GEN(c, bn)
179175a4d10SStefan Eßer #define BCL_CHECK_NUM_VALID(c, n)
180175a4d10SStefan Eßer 
181175a4d10SStefan Eßer #define BCL_NUM_ARRAY(bn) ((bn)->num)
182175a4d10SStefan Eßer #define BCL_NUM_ARRAY_NP(bn) ((bn).num)
183175a4d10SStefan Eßer 
184175a4d10SStefan Eßer #define BCL_NUM_NUM(bn) (bn)
185175a4d10SStefan Eßer #define BCL_NUM_NUM_NP(bn) (&(bn))
186175a4d10SStefan Eßer 
187175a4d10SStefan Eßer #endif // BC_ENABLE_MEMCHECK
188175a4d10SStefan Eßer 
18944d4804dSStefan Eßer /**
190d101cdd6SStefan Eßer  * A header that sets a jump.
191d101cdd6SStefan Eßer  * @param vm  The thread data.
19244d4804dSStefan Eßer  * @param l   The label to jump to on error.
19344d4804dSStefan Eßer  */
194d101cdd6SStefan Eßer #define BC_FUNC_HEADER(vm, l)     \
19578bc019dSStefan Eßer 	do                            \
19678bc019dSStefan Eßer 	{                             \
197d101cdd6SStefan Eßer 		BC_SETJMP(vm, l);         \
198d101cdd6SStefan Eßer 		vm->err = BCL_ERROR_NONE; \
19978bc019dSStefan Eßer 	}                             \
20078bc019dSStefan Eßer 	while (0)
20150696a6eSStefan Eßer 
20244d4804dSStefan Eßer /**
203d101cdd6SStefan Eßer  * A footer for functions that do not return an error code.
204d101cdd6SStefan Eßer  */
205d101cdd6SStefan Eßer #define BC_FUNC_FOOTER_NO_ERR(vm) \
206d101cdd6SStefan Eßer 	do                            \
207d101cdd6SStefan Eßer 	{                             \
208d101cdd6SStefan Eßer 		BC_UNSETJMP(vm);          \
209d101cdd6SStefan Eßer 	}                             \
210d101cdd6SStefan Eßer 	while (0)
211d101cdd6SStefan Eßer 
212d101cdd6SStefan Eßer /**
213d101cdd6SStefan Eßer  * A footer for functions that *do* return an error code.
214d101cdd6SStefan Eßer  * @param vm  The thread data.
21544d4804dSStefan Eßer  * @param e   The error variable to set.
21644d4804dSStefan Eßer  */
217d101cdd6SStefan Eßer #define BC_FUNC_FOOTER(vm, e)      \
21878bc019dSStefan Eßer 	do                             \
21978bc019dSStefan Eßer 	{                              \
220d101cdd6SStefan Eßer 		e = vm->err;               \
221d101cdd6SStefan Eßer 		BC_FUNC_FOOTER_NO_ERR(vm); \
22278bc019dSStefan Eßer 	}                              \
22378bc019dSStefan Eßer 	while (0)
22450696a6eSStefan Eßer 
22544d4804dSStefan Eßer /**
22644d4804dSStefan Eßer  * A footer that sets up n based the value of e and sets up the return value in
22744d4804dSStefan Eßer  * idx.
22844d4804dSStefan Eßer  * @param c    The context.
22944d4804dSStefan Eßer  * @param e    The error.
230175a4d10SStefan Eßer  * @param bn   The number.
23144d4804dSStefan Eßer  * @param idx  The idx to set as the return value.
23244d4804dSStefan Eßer  */
233175a4d10SStefan Eßer #define BC_MAYBE_SETUP(c, e, bn, idx)                                          \
23478bc019dSStefan Eßer 	do                                                                         \
23578bc019dSStefan Eßer 	{                                                                          \
23678bc019dSStefan Eßer 		if (BC_ERR((e) != BCL_ERROR_NONE))                                     \
23778bc019dSStefan Eßer 		{                                                                      \
238175a4d10SStefan Eßer 			if (BCL_NUM_ARRAY_NP(bn) != NULL) bc_num_free(BCL_NUM_NUM_NP(bn)); \
23950696a6eSStefan Eßer 			idx.i = 0 - (size_t) (e);                                          \
24050696a6eSStefan Eßer 		}                                                                      \
241175a4d10SStefan Eßer 		else idx = bcl_num_insert(c, &(bn));                                   \
24278bc019dSStefan Eßer 	}                                                                          \
24378bc019dSStefan Eßer 	while (0)
24450696a6eSStefan Eßer 
24544d4804dSStefan Eßer /**
24644d4804dSStefan Eßer  * A header to check the context and return an error encoded in a number if it
24744d4804dSStefan Eßer  * is bad.
24844d4804dSStefan Eßer  * @param c  The context.
24944d4804dSStefan Eßer  */
250d101cdd6SStefan Eßer #define BC_CHECK_CTXT(vm, c)                                   \
25178bc019dSStefan Eßer 	do                                                         \
25278bc019dSStefan Eßer 	{                                                          \
253d101cdd6SStefan Eßer 		c = bcl_contextHelper(vm);                             \
25478bc019dSStefan Eßer 		if (BC_ERR(c == NULL))                                 \
25578bc019dSStefan Eßer 		{                                                      \
256175a4d10SStefan Eßer 			BclNumber n_num_;                                  \
257175a4d10SStefan Eßer 			n_num_.i = 0 - (size_t) BCL_ERROR_INVALID_CONTEXT; \
258175a4d10SStefan Eßer 			return n_num_;                                     \
25950696a6eSStefan Eßer 		}                                                      \
26078bc019dSStefan Eßer 	}                                                          \
26178bc019dSStefan Eßer 	while (0)
26244d4804dSStefan Eßer 
26344d4804dSStefan Eßer /**
26444d4804dSStefan Eßer  * A header to check the context and return an error directly if it is bad.
26544d4804dSStefan Eßer  * @param c  The context.
26644d4804dSStefan Eßer  */
267d101cdd6SStefan Eßer #define BC_CHECK_CTXT_ERR(vm, c)              \
26878bc019dSStefan Eßer 	do                                        \
26978bc019dSStefan Eßer 	{                                         \
270d101cdd6SStefan Eßer 		c = bcl_contextHelper(vm);            \
27178bc019dSStefan Eßer 		if (BC_ERR(c == NULL))                \
27278bc019dSStefan Eßer 		{                                     \
27350696a6eSStefan Eßer 			return BCL_ERROR_INVALID_CONTEXT; \
27450696a6eSStefan Eßer 		}                                     \
27578bc019dSStefan Eßer 	}                                         \
27678bc019dSStefan Eßer 	while (0)
27750696a6eSStefan Eßer 
27844d4804dSStefan Eßer /**
27944d4804dSStefan Eßer  * A header to check the context and abort if it is bad.
28044d4804dSStefan Eßer  * @param c  The context.
28144d4804dSStefan Eßer  */
282d101cdd6SStefan Eßer #define BC_CHECK_CTXT_ASSERT(vm, c) \
28378bc019dSStefan Eßer 	do                              \
28478bc019dSStefan Eßer 	{                               \
285d101cdd6SStefan Eßer 		c = bcl_contextHelper(vm);  \
28650696a6eSStefan Eßer 		assert(c != NULL);          \
28778bc019dSStefan Eßer 	}                               \
28878bc019dSStefan Eßer 	while (0)
28950696a6eSStefan Eßer 
29044d4804dSStefan Eßer /**
29144d4804dSStefan Eßer  * A header to check the number in the context and return an error encoded as a
29244d4804dSStefan Eßer  * @param c  The context.
29344d4804dSStefan Eßer  * number if it is bad.
29444d4804dSStefan Eßer  * @param n  The BclNumber.
29544d4804dSStefan Eßer  */
29650696a6eSStefan Eßer #define BC_CHECK_NUM(c, n)                                         \
29778bc019dSStefan Eßer 	do                                                             \
29878bc019dSStefan Eßer 	{                                                              \
299175a4d10SStefan Eßer 		size_t no_gen_ = BCL_NO_GEN(n);                            \
300175a4d10SStefan Eßer 		if (BC_ERR(no_gen_ >= (c)->nums.len))                      \
30178bc019dSStefan Eßer 		{                                                          \
30250696a6eSStefan Eßer 			if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) return (n); \
30378bc019dSStefan Eßer 			else                                                   \
30478bc019dSStefan Eßer 			{                                                      \
305175a4d10SStefan Eßer 				BclNumber n_num_;                                  \
306175a4d10SStefan Eßer 				n_num_.i = 0 - (size_t) BCL_ERROR_INVALID_NUM;     \
307175a4d10SStefan Eßer 				return n_num_;                                     \
30850696a6eSStefan Eßer 			}                                                      \
30950696a6eSStefan Eßer 		}                                                          \
310175a4d10SStefan Eßer 		BCL_CHECK_NUM_GEN(c, n);                                   \
31178bc019dSStefan Eßer 	}                                                              \
31278bc019dSStefan Eßer 	while (0)
31378bc019dSStefan Eßer 
31478bc019dSStefan Eßer //clang-format off
31550696a6eSStefan Eßer 
31644d4804dSStefan Eßer /**
31744d4804dSStefan Eßer  * A header to check the number in the context and return an error directly if
31844d4804dSStefan Eßer  * it is bad.
31944d4804dSStefan Eßer  * @param c  The context.
32044d4804dSStefan Eßer  * @param n  The BclNumber.
32144d4804dSStefan Eßer  */
32250696a6eSStefan Eßer #define BC_CHECK_NUM_ERR(c, n)                         \
32378bc019dSStefan Eßer 	do                                                 \
32478bc019dSStefan Eßer 	{                                                  \
325175a4d10SStefan Eßer 		size_t no_gen_ = BCL_NO_GEN(n);                \
326175a4d10SStefan Eßer 		if (BC_ERR(no_gen_ >= (c)->nums.len))          \
32778bc019dSStefan Eßer 		{                                              \
32850696a6eSStefan Eßer 			if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) \
32978bc019dSStefan Eßer 			{                                          \
33050696a6eSStefan Eßer 				return (BclError) (0 - (n).i);         \
33178bc019dSStefan Eßer 			}                                          \
33250696a6eSStefan Eßer 			else return BCL_ERROR_INVALID_NUM;         \
33350696a6eSStefan Eßer 		}                                              \
334175a4d10SStefan Eßer 		BCL_CHECK_NUM_GEN(c, n);                       \
33578bc019dSStefan Eßer 	}                                                  \
33678bc019dSStefan Eßer 	while (0)
33778bc019dSStefan Eßer 
33878bc019dSStefan Eßer //clang-format on
33950696a6eSStefan Eßer 
34044d4804dSStefan Eßer /**
341175a4d10SStefan Eßer  * Grows the context's nums array if necessary.
34244d4804dSStefan Eßer  * @param c  The context.
34344d4804dSStefan Eßer  */
344175a4d10SStefan Eßer #define BCL_GROW_NUMS(c)                  \
345175a4d10SStefan Eßer 	do                                    \
346175a4d10SStefan Eßer 	{                                     \
347175a4d10SStefan Eßer 		if ((c)->free_nums.len == 0)      \
348175a4d10SStefan Eßer 		{                                 \
349175a4d10SStefan Eßer 			bc_vec_grow(&((c)->nums), 1); \
350175a4d10SStefan Eßer 		}                                 \
351175a4d10SStefan Eßer 	}                                     \
352175a4d10SStefan Eßer 	while (0)
35350696a6eSStefan Eßer 
35444d4804dSStefan Eßer /**
35544d4804dSStefan Eßer  * Frees a BcNum for bcl. This is a destructor.
35644d4804dSStefan Eßer  * @param num  The BcNum to free, as a void pointer.
35744d4804dSStefan Eßer  */
35878bc019dSStefan Eßer void
35978bc019dSStefan Eßer bcl_num_destruct(void* num);
36050696a6eSStefan Eßer 
36144d4804dSStefan Eßer /// The actual context struct.
36278bc019dSStefan Eßer typedef struct BclCtxt
36378bc019dSStefan Eßer {
36444d4804dSStefan Eßer 	/// The context's scale.
36550696a6eSStefan Eßer 	size_t scale;
36644d4804dSStefan Eßer 
36744d4804dSStefan Eßer 	/// The context's ibase.
36850696a6eSStefan Eßer 	size_t ibase;
36944d4804dSStefan Eßer 
37044d4804dSStefan Eßer 	/// The context's obase.
37150696a6eSStefan Eßer 	size_t obase;
37250696a6eSStefan Eßer 
37344d4804dSStefan Eßer 	/// A vector of BcNum numbers.
37450696a6eSStefan Eßer 	BcVec nums;
37544d4804dSStefan Eßer 
37644d4804dSStefan Eßer 	/// A vector of BclNumbers. These are the indices in nums that are currently
37744d4804dSStefan Eßer 	/// not used (because they were freed).
37850696a6eSStefan Eßer 	BcVec free_nums;
37950696a6eSStefan Eßer 
38050696a6eSStefan Eßer } BclCtxt;
38150696a6eSStefan Eßer 
382d101cdd6SStefan Eßer /**
383d101cdd6SStefan Eßer  * Returns the @a BcVm for the current thread.
384d101cdd6SStefan Eßer  * @return  The vm for the current thread.
385d101cdd6SStefan Eßer  */
386d101cdd6SStefan Eßer BcVm*
387d101cdd6SStefan Eßer bcl_getspecific(void);
388d101cdd6SStefan Eßer 
389d101cdd6SStefan Eßer #ifndef _WIN32
390d101cdd6SStefan Eßer 
391d101cdd6SStefan Eßer typedef pthread_key_t BclTls;
392d101cdd6SStefan Eßer 
393d101cdd6SStefan Eßer #else // _WIN32
394d101cdd6SStefan Eßer 
395d101cdd6SStefan Eßer typedef DWORD BclTls;
396d101cdd6SStefan Eßer 
397d101cdd6SStefan Eßer #endif // _WIN32
398d101cdd6SStefan Eßer 
39950696a6eSStefan Eßer #endif // LIBBC_PRIVATE_H
400