1*5a6e8488SAndroid Build Coastguard Worker /* 2*5a6e8488SAndroid Build Coastguard Worker * ***************************************************************************** 3*5a6e8488SAndroid Build Coastguard Worker * 4*5a6e8488SAndroid Build Coastguard Worker * SPDX-License-Identifier: BSD-2-Clause 5*5a6e8488SAndroid Build Coastguard Worker * 6*5a6e8488SAndroid Build Coastguard Worker * Copyright (c) 2018-2024 Gavin D. Howard and contributors. 7*5a6e8488SAndroid Build Coastguard Worker * 8*5a6e8488SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without 9*5a6e8488SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met: 10*5a6e8488SAndroid Build Coastguard Worker * 11*5a6e8488SAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright notice, this 12*5a6e8488SAndroid Build Coastguard Worker * list of conditions and the following disclaimer. 13*5a6e8488SAndroid Build Coastguard Worker * 14*5a6e8488SAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above copyright notice, 15*5a6e8488SAndroid Build Coastguard Worker * this list of conditions and the following disclaimer in the documentation 16*5a6e8488SAndroid Build Coastguard Worker * and/or other materials provided with the distribution. 17*5a6e8488SAndroid Build Coastguard Worker * 18*5a6e8488SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*5a6e8488SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*5a6e8488SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*5a6e8488SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*5a6e8488SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*5a6e8488SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*5a6e8488SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*5a6e8488SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*5a6e8488SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*5a6e8488SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*5a6e8488SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE. 29*5a6e8488SAndroid Build Coastguard Worker * 30*5a6e8488SAndroid Build Coastguard Worker * ***************************************************************************** 31*5a6e8488SAndroid Build Coastguard Worker * 32*5a6e8488SAndroid Build Coastguard Worker * The private header for the bc library. 33*5a6e8488SAndroid Build Coastguard Worker * 34*5a6e8488SAndroid Build Coastguard Worker */ 35*5a6e8488SAndroid Build Coastguard Worker 36*5a6e8488SAndroid Build Coastguard Worker #ifndef LIBBC_PRIVATE_H 37*5a6e8488SAndroid Build Coastguard Worker #define LIBBC_PRIVATE_H 38*5a6e8488SAndroid Build Coastguard Worker 39*5a6e8488SAndroid Build Coastguard Worker #ifndef _WIN32 40*5a6e8488SAndroid Build Coastguard Worker 41*5a6e8488SAndroid Build Coastguard Worker #include <pthread.h> 42*5a6e8488SAndroid Build Coastguard Worker 43*5a6e8488SAndroid Build Coastguard Worker #endif // _WIN32 44*5a6e8488SAndroid Build Coastguard Worker 45*5a6e8488SAndroid Build Coastguard Worker #include <bcl.h> 46*5a6e8488SAndroid Build Coastguard Worker 47*5a6e8488SAndroid Build Coastguard Worker #include <num.h> 48*5a6e8488SAndroid Build Coastguard Worker #include <vm.h> 49*5a6e8488SAndroid Build Coastguard Worker 50*5a6e8488SAndroid Build Coastguard Worker #if BC_ENABLE_MEMCHECK 51*5a6e8488SAndroid Build Coastguard Worker 52*5a6e8488SAndroid Build Coastguard Worker /** 53*5a6e8488SAndroid Build Coastguard Worker * A typedef for Valgrind builds. This is to add a generation index for error 54*5a6e8488SAndroid Build Coastguard Worker * checking. 55*5a6e8488SAndroid Build Coastguard Worker */ 56*5a6e8488SAndroid Build Coastguard Worker typedef struct BclNum 57*5a6e8488SAndroid Build Coastguard Worker { 58*5a6e8488SAndroid Build Coastguard Worker /// The number. 59*5a6e8488SAndroid Build Coastguard Worker BcNum n; 60*5a6e8488SAndroid Build Coastguard Worker 61*5a6e8488SAndroid Build Coastguard Worker /// The generation index. 62*5a6e8488SAndroid Build Coastguard Worker size_t gen_idx; 63*5a6e8488SAndroid Build Coastguard Worker 64*5a6e8488SAndroid Build Coastguard Worker } BclNum; 65*5a6e8488SAndroid Build Coastguard Worker 66*5a6e8488SAndroid Build Coastguard Worker /** 67*5a6e8488SAndroid Build Coastguard Worker * Clears the generation byte in a BclNumber and returns the value. 68*5a6e8488SAndroid Build Coastguard Worker * @param n The BclNumber. 69*5a6e8488SAndroid Build Coastguard Worker * @return The value of the index. 70*5a6e8488SAndroid Build Coastguard Worker */ 71*5a6e8488SAndroid Build Coastguard Worker #define BCL_NO_GEN(n) \ 72*5a6e8488SAndroid Build Coastguard Worker ((n).i & ~(((size_t) UCHAR_MAX) << ((sizeof(size_t) - 1) * CHAR_BIT))) 73*5a6e8488SAndroid Build Coastguard Worker 74*5a6e8488SAndroid Build Coastguard Worker /** 75*5a6e8488SAndroid Build Coastguard Worker * Gets the generation index in a BclNumber. 76*5a6e8488SAndroid Build Coastguard Worker * @param n The BclNumber. 77*5a6e8488SAndroid Build Coastguard Worker * @return The generation index. 78*5a6e8488SAndroid Build Coastguard Worker */ 79*5a6e8488SAndroid Build Coastguard Worker #define BCL_GET_GEN(n) ((n).i >> ((sizeof(size_t) - 1) * CHAR_BIT)) 80*5a6e8488SAndroid Build Coastguard Worker 81*5a6e8488SAndroid Build Coastguard Worker /** 82*5a6e8488SAndroid Build Coastguard Worker * Turns a BclNumber into a BcNum. 83*5a6e8488SAndroid Build Coastguard Worker * @param c The context. 84*5a6e8488SAndroid Build Coastguard Worker * @param n The BclNumber. 85*5a6e8488SAndroid Build Coastguard Worker */ 86*5a6e8488SAndroid Build Coastguard Worker #define BCL_NUM(c, n) ((BclNum*) bc_vec_item(&(c)->nums, BCL_NO_GEN(n))) 87*5a6e8488SAndroid Build Coastguard Worker 88*5a6e8488SAndroid Build Coastguard Worker /** 89*5a6e8488SAndroid Build Coastguard Worker * Clears the generation index top byte in the BclNumber. 90*5a6e8488SAndroid Build Coastguard Worker * @param n The BclNumber. 91*5a6e8488SAndroid Build Coastguard Worker */ 92*5a6e8488SAndroid Build Coastguard Worker #define BCL_CLEAR_GEN(n) \ 93*5a6e8488SAndroid Build Coastguard Worker do \ 94*5a6e8488SAndroid Build Coastguard Worker { \ 95*5a6e8488SAndroid Build Coastguard Worker (n).i &= ~(((size_t) UCHAR_MAX) << ((sizeof(size_t) - 1) * CHAR_BIT)); \ 96*5a6e8488SAndroid Build Coastguard Worker } \ 97*5a6e8488SAndroid Build Coastguard Worker while (0) 98*5a6e8488SAndroid Build Coastguard Worker 99*5a6e8488SAndroid Build Coastguard Worker #define BCL_CHECK_NUM_GEN(c, bn) \ 100*5a6e8488SAndroid Build Coastguard Worker do \ 101*5a6e8488SAndroid Build Coastguard Worker { \ 102*5a6e8488SAndroid Build Coastguard Worker size_t gen_ = BCL_GET_GEN(bn); \ 103*5a6e8488SAndroid Build Coastguard Worker BclNum* ptr_ = BCL_NUM(c, bn); \ 104*5a6e8488SAndroid Build Coastguard Worker if (BCL_NUM_ARRAY(ptr_) == NULL) \ 105*5a6e8488SAndroid Build Coastguard Worker { \ 106*5a6e8488SAndroid Build Coastguard Worker bcl_nonexistentNum(); \ 107*5a6e8488SAndroid Build Coastguard Worker } \ 108*5a6e8488SAndroid Build Coastguard Worker if (gen_ != ptr_->gen_idx) \ 109*5a6e8488SAndroid Build Coastguard Worker { \ 110*5a6e8488SAndroid Build Coastguard Worker bcl_invalidGeneration(); \ 111*5a6e8488SAndroid Build Coastguard Worker } \ 112*5a6e8488SAndroid Build Coastguard Worker } \ 113*5a6e8488SAndroid Build Coastguard Worker while (0) 114*5a6e8488SAndroid Build Coastguard Worker 115*5a6e8488SAndroid Build Coastguard Worker #define BCL_CHECK_NUM_VALID(c, bn) \ 116*5a6e8488SAndroid Build Coastguard Worker do \ 117*5a6e8488SAndroid Build Coastguard Worker { \ 118*5a6e8488SAndroid Build Coastguard Worker size_t idx_ = BCL_NO_GEN(bn); \ 119*5a6e8488SAndroid Build Coastguard Worker if ((c)->nums.len <= idx_) \ 120*5a6e8488SAndroid Build Coastguard Worker { \ 121*5a6e8488SAndroid Build Coastguard Worker bcl_numIdxOutOfRange(); \ 122*5a6e8488SAndroid Build Coastguard Worker } \ 123*5a6e8488SAndroid Build Coastguard Worker BCL_CHECK_NUM_GEN(c, bn); \ 124*5a6e8488SAndroid Build Coastguard Worker } \ 125*5a6e8488SAndroid Build Coastguard Worker while (0) 126*5a6e8488SAndroid Build Coastguard Worker 127*5a6e8488SAndroid Build Coastguard Worker /** 128*5a6e8488SAndroid Build Coastguard Worker * Returns the limb array of the number. 129*5a6e8488SAndroid Build Coastguard Worker * @param bn The number. 130*5a6e8488SAndroid Build Coastguard Worker * @return The limb array. 131*5a6e8488SAndroid Build Coastguard Worker */ 132*5a6e8488SAndroid Build Coastguard Worker #define BCL_NUM_ARRAY(bn) ((bn)->n.num) 133*5a6e8488SAndroid Build Coastguard Worker 134*5a6e8488SAndroid Build Coastguard Worker /** 135*5a6e8488SAndroid Build Coastguard Worker * Returns the limb array of the number for a non-pointer. 136*5a6e8488SAndroid Build Coastguard Worker * @param bn The number. 137*5a6e8488SAndroid Build Coastguard Worker * @return The limb array. 138*5a6e8488SAndroid Build Coastguard Worker */ 139*5a6e8488SAndroid Build Coastguard Worker #define BCL_NUM_ARRAY_NP(bn) ((bn).n.num) 140*5a6e8488SAndroid Build Coastguard Worker 141*5a6e8488SAndroid Build Coastguard Worker /** 142*5a6e8488SAndroid Build Coastguard Worker * Returns the BcNum pointer. 143*5a6e8488SAndroid Build Coastguard Worker * @param bn The number. 144*5a6e8488SAndroid Build Coastguard Worker * @return The BcNum pointer. 145*5a6e8488SAndroid Build Coastguard Worker */ 146*5a6e8488SAndroid Build Coastguard Worker #define BCL_NUM_NUM(bn) (&(bn)->n) 147*5a6e8488SAndroid Build Coastguard Worker 148*5a6e8488SAndroid Build Coastguard Worker /** 149*5a6e8488SAndroid Build Coastguard Worker * Returns the BcNum pointer for a non-pointer. 150*5a6e8488SAndroid Build Coastguard Worker * @param bn The number. 151*5a6e8488SAndroid Build Coastguard Worker * @return The BcNum pointer. 152*5a6e8488SAndroid Build Coastguard Worker */ 153*5a6e8488SAndroid Build Coastguard Worker #define BCL_NUM_NUM_NP(bn) (&(bn).n) 154*5a6e8488SAndroid Build Coastguard Worker 155*5a6e8488SAndroid Build Coastguard Worker // These functions only abort. They exist to give developers some idea of what 156*5a6e8488SAndroid Build Coastguard Worker // went wrong when bugs are found, if they look at the Valgrind stack trace. 157*5a6e8488SAndroid Build Coastguard Worker 158*5a6e8488SAndroid Build Coastguard Worker BC_NORETURN void 159*5a6e8488SAndroid Build Coastguard Worker bcl_invalidGeneration(void); 160*5a6e8488SAndroid Build Coastguard Worker 161*5a6e8488SAndroid Build Coastguard Worker BC_NORETURN void 162*5a6e8488SAndroid Build Coastguard Worker bcl_nonexistentNum(void); 163*5a6e8488SAndroid Build Coastguard Worker 164*5a6e8488SAndroid Build Coastguard Worker BC_NORETURN void 165*5a6e8488SAndroid Build Coastguard Worker bcl_numIdxOutOfRange(void); 166*5a6e8488SAndroid Build Coastguard Worker 167*5a6e8488SAndroid Build Coastguard Worker #else // BC_ENABLE_MEMCHECK 168*5a6e8488SAndroid Build Coastguard Worker 169*5a6e8488SAndroid Build Coastguard Worker /** 170*5a6e8488SAndroid Build Coastguard Worker * A typedef for non-Valgrind builds. 171*5a6e8488SAndroid Build Coastguard Worker */ 172*5a6e8488SAndroid Build Coastguard Worker typedef BcNum BclNum; 173*5a6e8488SAndroid Build Coastguard Worker 174*5a6e8488SAndroid Build Coastguard Worker #define BCL_NO_GEN(n) ((n).i) 175*5a6e8488SAndroid Build Coastguard Worker #define BCL_NUM(c, n) ((BclNum*) bc_vec_item(&(c)->nums, (n).i)) 176*5a6e8488SAndroid Build Coastguard Worker #define BCL_CLEAR_GEN(n) ((void) (n)) 177*5a6e8488SAndroid Build Coastguard Worker 178*5a6e8488SAndroid Build Coastguard Worker #define BCL_CHECK_NUM_GEN(c, bn) 179*5a6e8488SAndroid Build Coastguard Worker #define BCL_CHECK_NUM_VALID(c, n) 180*5a6e8488SAndroid Build Coastguard Worker 181*5a6e8488SAndroid Build Coastguard Worker #define BCL_NUM_ARRAY(bn) ((bn)->num) 182*5a6e8488SAndroid Build Coastguard Worker #define BCL_NUM_ARRAY_NP(bn) ((bn).num) 183*5a6e8488SAndroid Build Coastguard Worker 184*5a6e8488SAndroid Build Coastguard Worker #define BCL_NUM_NUM(bn) (bn) 185*5a6e8488SAndroid Build Coastguard Worker #define BCL_NUM_NUM_NP(bn) (&(bn)) 186*5a6e8488SAndroid Build Coastguard Worker 187*5a6e8488SAndroid Build Coastguard Worker #endif // BC_ENABLE_MEMCHECK 188*5a6e8488SAndroid Build Coastguard Worker 189*5a6e8488SAndroid Build Coastguard Worker /** 190*5a6e8488SAndroid Build Coastguard Worker * A header that sets a jump. 191*5a6e8488SAndroid Build Coastguard Worker * @param vm The thread data. 192*5a6e8488SAndroid Build Coastguard Worker * @param l The label to jump to on error. 193*5a6e8488SAndroid Build Coastguard Worker */ 194*5a6e8488SAndroid Build Coastguard Worker #define BC_FUNC_HEADER(vm, l) \ 195*5a6e8488SAndroid Build Coastguard Worker do \ 196*5a6e8488SAndroid Build Coastguard Worker { \ 197*5a6e8488SAndroid Build Coastguard Worker BC_SETJMP(vm, l); \ 198*5a6e8488SAndroid Build Coastguard Worker vm->err = BCL_ERROR_NONE; \ 199*5a6e8488SAndroid Build Coastguard Worker } \ 200*5a6e8488SAndroid Build Coastguard Worker while (0) 201*5a6e8488SAndroid Build Coastguard Worker 202*5a6e8488SAndroid Build Coastguard Worker /** 203*5a6e8488SAndroid Build Coastguard Worker * A footer for functions that do not return an error code. 204*5a6e8488SAndroid Build Coastguard Worker */ 205*5a6e8488SAndroid Build Coastguard Worker #define BC_FUNC_FOOTER_NO_ERR(vm) \ 206*5a6e8488SAndroid Build Coastguard Worker do \ 207*5a6e8488SAndroid Build Coastguard Worker { \ 208*5a6e8488SAndroid Build Coastguard Worker BC_UNSETJMP(vm); \ 209*5a6e8488SAndroid Build Coastguard Worker } \ 210*5a6e8488SAndroid Build Coastguard Worker while (0) 211*5a6e8488SAndroid Build Coastguard Worker 212*5a6e8488SAndroid Build Coastguard Worker /** 213*5a6e8488SAndroid Build Coastguard Worker * A footer for functions that *do* return an error code. 214*5a6e8488SAndroid Build Coastguard Worker * @param vm The thread data. 215*5a6e8488SAndroid Build Coastguard Worker * @param e The error variable to set. 216*5a6e8488SAndroid Build Coastguard Worker */ 217*5a6e8488SAndroid Build Coastguard Worker #define BC_FUNC_FOOTER(vm, e) \ 218*5a6e8488SAndroid Build Coastguard Worker do \ 219*5a6e8488SAndroid Build Coastguard Worker { \ 220*5a6e8488SAndroid Build Coastguard Worker e = vm->err; \ 221*5a6e8488SAndroid Build Coastguard Worker BC_FUNC_FOOTER_NO_ERR(vm); \ 222*5a6e8488SAndroid Build Coastguard Worker } \ 223*5a6e8488SAndroid Build Coastguard Worker while (0) 224*5a6e8488SAndroid Build Coastguard Worker 225*5a6e8488SAndroid Build Coastguard Worker /** 226*5a6e8488SAndroid Build Coastguard Worker * A footer that sets up n based the value of e and sets up the return value in 227*5a6e8488SAndroid Build Coastguard Worker * idx. 228*5a6e8488SAndroid Build Coastguard Worker * @param c The context. 229*5a6e8488SAndroid Build Coastguard Worker * @param e The error. 230*5a6e8488SAndroid Build Coastguard Worker * @param bn The number. 231*5a6e8488SAndroid Build Coastguard Worker * @param idx The idx to set as the return value. 232*5a6e8488SAndroid Build Coastguard Worker */ 233*5a6e8488SAndroid Build Coastguard Worker #define BC_MAYBE_SETUP(c, e, bn, idx) \ 234*5a6e8488SAndroid Build Coastguard Worker do \ 235*5a6e8488SAndroid Build Coastguard Worker { \ 236*5a6e8488SAndroid Build Coastguard Worker if (BC_ERR((e) != BCL_ERROR_NONE)) \ 237*5a6e8488SAndroid Build Coastguard Worker { \ 238*5a6e8488SAndroid Build Coastguard Worker if (BCL_NUM_ARRAY_NP(bn) != NULL) bc_num_free(BCL_NUM_NUM_NP(bn)); \ 239*5a6e8488SAndroid Build Coastguard Worker idx.i = 0 - (size_t) (e); \ 240*5a6e8488SAndroid Build Coastguard Worker } \ 241*5a6e8488SAndroid Build Coastguard Worker else idx = bcl_num_insert(c, &(bn)); \ 242*5a6e8488SAndroid Build Coastguard Worker } \ 243*5a6e8488SAndroid Build Coastguard Worker while (0) 244*5a6e8488SAndroid Build Coastguard Worker 245*5a6e8488SAndroid Build Coastguard Worker /** 246*5a6e8488SAndroid Build Coastguard Worker * A header to check the context and return an error encoded in a number if it 247*5a6e8488SAndroid Build Coastguard Worker * is bad. 248*5a6e8488SAndroid Build Coastguard Worker * @param c The context. 249*5a6e8488SAndroid Build Coastguard Worker */ 250*5a6e8488SAndroid Build Coastguard Worker #define BC_CHECK_CTXT(vm, c) \ 251*5a6e8488SAndroid Build Coastguard Worker do \ 252*5a6e8488SAndroid Build Coastguard Worker { \ 253*5a6e8488SAndroid Build Coastguard Worker c = bcl_contextHelper(vm); \ 254*5a6e8488SAndroid Build Coastguard Worker if (BC_ERR(c == NULL)) \ 255*5a6e8488SAndroid Build Coastguard Worker { \ 256*5a6e8488SAndroid Build Coastguard Worker BclNumber n_num_; \ 257*5a6e8488SAndroid Build Coastguard Worker n_num_.i = 0 - (size_t) BCL_ERROR_INVALID_CONTEXT; \ 258*5a6e8488SAndroid Build Coastguard Worker return n_num_; \ 259*5a6e8488SAndroid Build Coastguard Worker } \ 260*5a6e8488SAndroid Build Coastguard Worker } \ 261*5a6e8488SAndroid Build Coastguard Worker while (0) 262*5a6e8488SAndroid Build Coastguard Worker 263*5a6e8488SAndroid Build Coastguard Worker /** 264*5a6e8488SAndroid Build Coastguard Worker * A header to check the context and return an error directly if it is bad. 265*5a6e8488SAndroid Build Coastguard Worker * @param c The context. 266*5a6e8488SAndroid Build Coastguard Worker */ 267*5a6e8488SAndroid Build Coastguard Worker #define BC_CHECK_CTXT_ERR(vm, c) \ 268*5a6e8488SAndroid Build Coastguard Worker do \ 269*5a6e8488SAndroid Build Coastguard Worker { \ 270*5a6e8488SAndroid Build Coastguard Worker c = bcl_contextHelper(vm); \ 271*5a6e8488SAndroid Build Coastguard Worker if (BC_ERR(c == NULL)) \ 272*5a6e8488SAndroid Build Coastguard Worker { \ 273*5a6e8488SAndroid Build Coastguard Worker return BCL_ERROR_INVALID_CONTEXT; \ 274*5a6e8488SAndroid Build Coastguard Worker } \ 275*5a6e8488SAndroid Build Coastguard Worker } \ 276*5a6e8488SAndroid Build Coastguard Worker while (0) 277*5a6e8488SAndroid Build Coastguard Worker 278*5a6e8488SAndroid Build Coastguard Worker /** 279*5a6e8488SAndroid Build Coastguard Worker * A header to check the context and abort if it is bad. 280*5a6e8488SAndroid Build Coastguard Worker * @param c The context. 281*5a6e8488SAndroid Build Coastguard Worker */ 282*5a6e8488SAndroid Build Coastguard Worker #define BC_CHECK_CTXT_ASSERT(vm, c) \ 283*5a6e8488SAndroid Build Coastguard Worker do \ 284*5a6e8488SAndroid Build Coastguard Worker { \ 285*5a6e8488SAndroid Build Coastguard Worker c = bcl_contextHelper(vm); \ 286*5a6e8488SAndroid Build Coastguard Worker assert(c != NULL); \ 287*5a6e8488SAndroid Build Coastguard Worker } \ 288*5a6e8488SAndroid Build Coastguard Worker while (0) 289*5a6e8488SAndroid Build Coastguard Worker 290*5a6e8488SAndroid Build Coastguard Worker /** 291*5a6e8488SAndroid Build Coastguard Worker * A header to check the number in the context and return an error encoded as a 292*5a6e8488SAndroid Build Coastguard Worker * @param c The context. 293*5a6e8488SAndroid Build Coastguard Worker * number if it is bad. 294*5a6e8488SAndroid Build Coastguard Worker * @param n The BclNumber. 295*5a6e8488SAndroid Build Coastguard Worker */ 296*5a6e8488SAndroid Build Coastguard Worker #define BC_CHECK_NUM(c, n) \ 297*5a6e8488SAndroid Build Coastguard Worker do \ 298*5a6e8488SAndroid Build Coastguard Worker { \ 299*5a6e8488SAndroid Build Coastguard Worker size_t no_gen_ = BCL_NO_GEN(n); \ 300*5a6e8488SAndroid Build Coastguard Worker if (BC_ERR(no_gen_ >= (c)->nums.len)) \ 301*5a6e8488SAndroid Build Coastguard Worker { \ 302*5a6e8488SAndroid Build Coastguard Worker if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) return (n); \ 303*5a6e8488SAndroid Build Coastguard Worker else \ 304*5a6e8488SAndroid Build Coastguard Worker { \ 305*5a6e8488SAndroid Build Coastguard Worker BclNumber n_num_; \ 306*5a6e8488SAndroid Build Coastguard Worker n_num_.i = 0 - (size_t) BCL_ERROR_INVALID_NUM; \ 307*5a6e8488SAndroid Build Coastguard Worker return n_num_; \ 308*5a6e8488SAndroid Build Coastguard Worker } \ 309*5a6e8488SAndroid Build Coastguard Worker } \ 310*5a6e8488SAndroid Build Coastguard Worker BCL_CHECK_NUM_GEN(c, n); \ 311*5a6e8488SAndroid Build Coastguard Worker } \ 312*5a6e8488SAndroid Build Coastguard Worker while (0) 313*5a6e8488SAndroid Build Coastguard Worker 314*5a6e8488SAndroid Build Coastguard Worker //clang-format off 315*5a6e8488SAndroid Build Coastguard Worker 316*5a6e8488SAndroid Build Coastguard Worker /** 317*5a6e8488SAndroid Build Coastguard Worker * A header to check the number in the context and return an error directly if 318*5a6e8488SAndroid Build Coastguard Worker * it is bad. 319*5a6e8488SAndroid Build Coastguard Worker * @param c The context. 320*5a6e8488SAndroid Build Coastguard Worker * @param n The BclNumber. 321*5a6e8488SAndroid Build Coastguard Worker */ 322*5a6e8488SAndroid Build Coastguard Worker #define BC_CHECK_NUM_ERR(c, n) \ 323*5a6e8488SAndroid Build Coastguard Worker do \ 324*5a6e8488SAndroid Build Coastguard Worker { \ 325*5a6e8488SAndroid Build Coastguard Worker size_t no_gen_ = BCL_NO_GEN(n); \ 326*5a6e8488SAndroid Build Coastguard Worker if (BC_ERR(no_gen_ >= (c)->nums.len)) \ 327*5a6e8488SAndroid Build Coastguard Worker { \ 328*5a6e8488SAndroid Build Coastguard Worker if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) \ 329*5a6e8488SAndroid Build Coastguard Worker { \ 330*5a6e8488SAndroid Build Coastguard Worker return (BclError) (0 - (n).i); \ 331*5a6e8488SAndroid Build Coastguard Worker } \ 332*5a6e8488SAndroid Build Coastguard Worker else return BCL_ERROR_INVALID_NUM; \ 333*5a6e8488SAndroid Build Coastguard Worker } \ 334*5a6e8488SAndroid Build Coastguard Worker BCL_CHECK_NUM_GEN(c, n); \ 335*5a6e8488SAndroid Build Coastguard Worker } \ 336*5a6e8488SAndroid Build Coastguard Worker while (0) 337*5a6e8488SAndroid Build Coastguard Worker 338*5a6e8488SAndroid Build Coastguard Worker //clang-format on 339*5a6e8488SAndroid Build Coastguard Worker 340*5a6e8488SAndroid Build Coastguard Worker /** 341*5a6e8488SAndroid Build Coastguard Worker * Grows the context's nums array if necessary. 342*5a6e8488SAndroid Build Coastguard Worker * @param c The context. 343*5a6e8488SAndroid Build Coastguard Worker */ 344*5a6e8488SAndroid Build Coastguard Worker #define BCL_GROW_NUMS(c) \ 345*5a6e8488SAndroid Build Coastguard Worker do \ 346*5a6e8488SAndroid Build Coastguard Worker { \ 347*5a6e8488SAndroid Build Coastguard Worker if ((c)->free_nums.len == 0) \ 348*5a6e8488SAndroid Build Coastguard Worker { \ 349*5a6e8488SAndroid Build Coastguard Worker bc_vec_grow(&((c)->nums), 1); \ 350*5a6e8488SAndroid Build Coastguard Worker } \ 351*5a6e8488SAndroid Build Coastguard Worker } \ 352*5a6e8488SAndroid Build Coastguard Worker while (0) 353*5a6e8488SAndroid Build Coastguard Worker 354*5a6e8488SAndroid Build Coastguard Worker /** 355*5a6e8488SAndroid Build Coastguard Worker * Frees a BcNum for bcl. This is a destructor. 356*5a6e8488SAndroid Build Coastguard Worker * @param num The BcNum to free, as a void pointer. 357*5a6e8488SAndroid Build Coastguard Worker */ 358*5a6e8488SAndroid Build Coastguard Worker void 359*5a6e8488SAndroid Build Coastguard Worker bcl_num_destruct(void* num); 360*5a6e8488SAndroid Build Coastguard Worker 361*5a6e8488SAndroid Build Coastguard Worker /// The actual context struct. 362*5a6e8488SAndroid Build Coastguard Worker typedef struct BclCtxt 363*5a6e8488SAndroid Build Coastguard Worker { 364*5a6e8488SAndroid Build Coastguard Worker /// The context's scale. 365*5a6e8488SAndroid Build Coastguard Worker size_t scale; 366*5a6e8488SAndroid Build Coastguard Worker 367*5a6e8488SAndroid Build Coastguard Worker /// The context's ibase. 368*5a6e8488SAndroid Build Coastguard Worker size_t ibase; 369*5a6e8488SAndroid Build Coastguard Worker 370*5a6e8488SAndroid Build Coastguard Worker /// The context's obase. 371*5a6e8488SAndroid Build Coastguard Worker size_t obase; 372*5a6e8488SAndroid Build Coastguard Worker 373*5a6e8488SAndroid Build Coastguard Worker /// A vector of BcNum numbers. 374*5a6e8488SAndroid Build Coastguard Worker BcVec nums; 375*5a6e8488SAndroid Build Coastguard Worker 376*5a6e8488SAndroid Build Coastguard Worker /// A vector of BclNumbers. These are the indices in nums that are currently 377*5a6e8488SAndroid Build Coastguard Worker /// not used (because they were freed). 378*5a6e8488SAndroid Build Coastguard Worker BcVec free_nums; 379*5a6e8488SAndroid Build Coastguard Worker 380*5a6e8488SAndroid Build Coastguard Worker } BclCtxt; 381*5a6e8488SAndroid Build Coastguard Worker 382*5a6e8488SAndroid Build Coastguard Worker /** 383*5a6e8488SAndroid Build Coastguard Worker * Returns the @a BcVm for the current thread. 384*5a6e8488SAndroid Build Coastguard Worker * @return The vm for the current thread. 385*5a6e8488SAndroid Build Coastguard Worker */ 386*5a6e8488SAndroid Build Coastguard Worker BcVm* 387*5a6e8488SAndroid Build Coastguard Worker bcl_getspecific(void); 388*5a6e8488SAndroid Build Coastguard Worker 389*5a6e8488SAndroid Build Coastguard Worker #ifndef _WIN32 390*5a6e8488SAndroid Build Coastguard Worker 391*5a6e8488SAndroid Build Coastguard Worker typedef pthread_key_t BclTls; 392*5a6e8488SAndroid Build Coastguard Worker 393*5a6e8488SAndroid Build Coastguard Worker #else // _WIN32 394*5a6e8488SAndroid Build Coastguard Worker 395*5a6e8488SAndroid Build Coastguard Worker typedef DWORD BclTls; 396*5a6e8488SAndroid Build Coastguard Worker 397*5a6e8488SAndroid Build Coastguard Worker #endif // _WIN32 398*5a6e8488SAndroid Build Coastguard Worker 399*5a6e8488SAndroid Build Coastguard Worker #endif // LIBBC_PRIVATE_H 400