BLI_stackdefines
authorCampbell Barton <ideasman42@gmail.com>
Sat, 28 Jun 2014 19:06:22 +0000 (05:06 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 28 Jun 2014 19:57:48 +0000 (05:57 +1000)
Bounds check the stack while debugging, also add STACK_PEEK

source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenlib/BLI_stackdefines.h
source/blender/bmesh/intern/bmesh_core.c
source/blender/bmesh/intern/bmesh_queries.c
source/blender/bmesh/operators/bmo_bisect_plane.c
source/blender/bmesh/operators/bmo_connect.c
source/blender/bmesh/operators/bmo_removedoubles.c
source/blender/bmesh/operators/bmo_subdivide_edgering.c
source/blender/bmesh/tools/bmesh_bisect_plane.c
source/blender/modifiers/intern/MOD_solidify.c

index 2d7e06c7308f5dd0e9a3ba5725f5c47a1d096bb7..3f8edbcf1bed75a55e35f550c1d620c31da6c09e 100644 (file)
@@ -2602,15 +2602,15 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
 
        int i, j, c;
        
-       STACK_INIT(oldv);
-       STACK_INIT(olde);
-       STACK_INIT(oldl);
-       STACK_INIT(oldp);
-
-       STACK_INIT(mvert);
-       STACK_INIT(medge);
-       STACK_INIT(mloop);
-       STACK_INIT(mpoly);
+       STACK_INIT(oldv, totvert_final);
+       STACK_INIT(olde, totedge);
+       STACK_INIT(oldl, totloop);
+       STACK_INIT(oldp, totpoly);
+
+       STACK_INIT(mvert, totvert_final);
+       STACK_INIT(medge, totedge);
+       STACK_INIT(mloop, totloop);
+       STACK_INIT(mpoly, totpoly);
 
        /* fill newl with destination vertex indices */
        mv = cddm->mvert;
index 3a4957599d66ce764031c80aca3a1331ec83e97f..24cb043cd4376fadd9833aa956a11b63c1e6653e 100644 (file)
 
 /** \file BLI_stackdefines.h
  *  \ingroup bli
+ *
+ * Macro's for a simple array based stack
+ * \note Caller handles alloc & free).
  */
 
-/* simple stack */
-#define STACK_DECLARE(stack)   unsigned int _##stack##_index
-#define STACK_INIT(stack)      ((void)stack, (void)((_##stack##_index) = 0))
-#define STACK_SIZE(stack)      ((void)stack, (_##stack##_index))
-#define STACK_PUSH(stack, val)  (void)((stack)[(_##stack##_index)++] = val)
-#define STACK_PUSH_RET(stack)  ((void)stack, ((stack)[(_##stack##_index)++]))
-#define STACK_PUSH_RET_PTR(stack)  ((void)stack, &((stack)[(_##stack##_index)++]))
+/* only validate array-bounds in debug mode */
+#ifdef DEBUG
+#  define STACK_DECLARE(stack)   unsigned int _##stack##_index, _##stack##_totalloc
+#  define STACK_INIT(stack, tot) ((void)stack, (void)((_##stack##_index) = 0), (void)((_##stack##_totalloc) = tot))
+#  define _STACK_SIZETEST(stack, off) (BLI_assert((_##stack##_index) + off <= _##stack##_totalloc))
+#  define _STACK_SWAP_TOTALLOC(stack_a, stack_b) SWAP(unsigned int, _##stack_a##_totalloc, _##stack_b##_totalloc)
+#else
+#  define STACK_DECLARE(stack)   unsigned int _##stack##_index
+#  define STACK_INIT(stack, tot) ((void)stack, (void)((_##stack##_index) = 0), (void)(tot))
+#  define _STACK_SIZETEST(stack, off) (void)(stack), (void)(off)
+#  define _STACK_SWAP_TOTALLOC(stack_a, stack_b) (void)(stack_a), (void)(stack_b)
+#endif
+#define _STACK_BOUNDSTEST(stack, index) ((void)stack, BLI_assert(index >= 0 && index < _##stack##_index))
+
+
+#define STACK_SIZE(stack)           ((void)stack, (_##stack##_index))
+/** add item to stack */
+#define STACK_PUSH(stack, val)      ((void)stack, _STACK_SIZETEST(stack, 1),  ((stack)[(_##stack##_index)++] = val))
+#define STACK_PUSH_RET(stack)       ((void)stack, _STACK_SIZETEST(stack, 1),  ((stack)[(_##stack##_index)++]))
+#define STACK_PUSH_RET_PTR(stack)   ((void)stack, _STACK_SIZETEST(stack, 1), &((stack)[(_##stack##_index)++]))
+/** take last item from stack */
 #define STACK_POP(stack)            ((_##stack##_index) ?  ((stack)[--(_##stack##_index)]) : NULL)
 #define STACK_POP_PTR(stack)        ((_##stack##_index) ? &((stack)[--(_##stack##_index)]) : NULL)
 #define STACK_POP_DEFAULT(stack, r) ((_##stack##_index) ?  ((stack)[--(_##stack##_index)]) : r)
-/* take care, re-orders */
+/** look at last item (assumes non-empty stack) */
+#define STACK_PEEK(stack)           (BLI_assert(_##stack##_index),  ((stack)[_##stack##_index - 1]))
+#define STACK_PEEK_PTR(stack)       (BLI_assert(_##stack##_index), &((stack)[_##stack##_index - 1]))
+/** remove any item from the stack, take care, re-orders */
 #define STACK_REMOVE(stack, i) \
+       _STACK_BOUNDSTEST(stack, i); \
        if (--_##stack##_index != i) { \
                stack[i] = stack[_##stack##_index]; \
        } (void)0
 #define STACK_SWAP(stack_a, stack_b) { \
        SWAP(typeof(stack_a), stack_a, stack_b); \
        SWAP(unsigned int, _##stack_a##_index, _##stack_b##_index); \
+       _STACK_SWAP_TOTALLOC(stack_a, stack_b); \
        } (void)0
 #else
 #define STACK_SWAP(stack_a, stack_b) { \
        SWAP(void *, stack_a, stack_b); \
        SWAP(unsigned int, _##stack_a##_index, _##stack_b##_index); \
+       _STACK_SWAP_TOTALLOC(stack_a, stack_b); \
        } (void)0
 #endif
 
index c4dc990918587a8efe6983bc6dcd77a80efa3023..1c93eccf8bd46c8f446106dc430918a1863321f5 100644 (file)
@@ -2038,7 +2038,7 @@ void bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len
 
        BLI_smallhash_init_ex(&visithash, v_edgetot);
 
-       STACK_INIT(stack);
+       STACK_INIT(stack, v_edgetot);
 
        maxindex = 0;
        BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
@@ -2109,7 +2109,7 @@ void bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len
         * by modifying data it loops over [#30632], this re-uses the 'stack' variable which is a bit
         * bad practice but save alloc'ing a new array - note, the comment above is useful, keep it
         * if you are tidying up code - campbell */
-       STACK_INIT(stack);
+       STACK_INIT(stack, v_edgetot);
        BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
                if (l->v == v) {
                        STACK_PUSH(stack, (BMEdge *)l);
index d478ac074745116bd6035c663ca87a34b19ffb76..606e93d4a85a6d35cbf056bf18c4435a9f1cd93a 100644 (file)
@@ -2068,7 +2068,7 @@ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde
        BMFace *f;
        int i;
 
-       STACK_INIT(group_array);
+       STACK_INIT(group_array, bm->totface);
 
        BLI_assert(((htype_step & ~(BM_VERT | BM_EDGE)) == 0) && (htype_step != 0));
 
@@ -2096,7 +2096,7 @@ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde
 
                BLI_assert(tot_touch < tot_faces);
 
-               STACK_INIT(stack);
+               STACK_INIT(stack, tot_faces);
 
                BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
                        if (BM_elem_flag_test(f, BM_ELEM_TAG) == false) {
@@ -2224,7 +2224,7 @@ int BM_mesh_calc_edge_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde
        BMEdge *e;
        int i;
 
-       STACK_INIT(group_array);
+       STACK_INIT(group_array, bm->totface);
 
        /* init the array */
        BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
@@ -2250,7 +2250,7 @@ int BM_mesh_calc_edge_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde
 
                BLI_assert(tot_touch < tot_edges);
 
-               STACK_INIT(stack);
+               STACK_INIT(stack, tot_edges);
 
                BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
                        if (BM_elem_flag_test(e, BM_ELEM_TAG) == false) {
index 378cf405e1663bdaff5c7326583d2ee588c7efc7..bed1ea5cb949702dfc6bdc3e0dca1e4c4433a9fa 100644 (file)
@@ -90,7 +90,7 @@ void bmo_bisect_plane_exec(BMesh *bm, BMOperator *op)
                plane_outer[3] = plane[3] - dist;
                plane_inner[3] = plane[3] + dist;
 
-               STACK_INIT(vert_arr);
+               STACK_INIT(vert_arr, vert_arr_max);
 
                BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
                        if ((clear_outer && plane_point_side_v3(plane_outer, v->co) > 0.0f) ||
index 8b0033a9342a004501c5c017300a282d49eff69d..4cf6e82fc8ea7833a9ae059f2018f731dfc18d11 100644 (file)
@@ -52,8 +52,8 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f, const bool check_degenera
        BMLoop *l_last;
        unsigned int i;
 
-       STACK_INIT(loops_split);
-       STACK_INIT(verts_pair);
+       STACK_INIT(loops_split, f->len);
+       STACK_INIT(verts_pair, f->len);
 
        l_last = NULL;
        BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
index a17ab2133c1cb6334954f688f00b58d5be9fdcae..814649c7dbf12423a0c040512772134be1bcf340 100644 (file)
@@ -92,8 +92,8 @@ static void remdoubles_createface(BMesh *bm, BMFace *f, BMOpSlot *slot_targetmap
        STACK_DECLARE(edges);
        STACK_DECLARE(loops);
 
-       STACK_INIT(edges);
-       STACK_INIT(loops);
+       STACK_INIT(edges, f->len);
+       STACK_INIT(loops, f->len);
 
        BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
                BMVert *v1 = l->v;
index ae1ff5a7389755bd4a7691a6e21dc21563216465..e13a9df4474716468b5471d1b3bdc560400f4f4d 100644 (file)
@@ -970,8 +970,8 @@ static void bm_edgering_pair_subdiv(BMesh *bm,
        BMEdge *e;
        BMFace *f;
 
-       STACK_INIT(edges_ring_arr);
-       STACK_INIT(faces_ring_arr);
+       STACK_INIT(edges_ring_arr, stack_max);
+       STACK_INIT(faces_ring_arr, stack_max);
 
        bm_edgeloop_vert_tag(el_store_a, false);
        bm_edgeloop_vert_tag(el_store_b, true);
index 0bd68e7a4617005366b7cd7e4430873c6933f4b7..0ecb8066ac12e923d09d3b59d320b0474cc3c3b6 100644 (file)
@@ -118,7 +118,7 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
        BMLoop *l_iter, *l_first;
        bool use_dirs[3] = {false, false, false};
 
-       STACK_INIT(vert_split_arr);
+       STACK_INIT(vert_split_arr, f_len_orig);
 
        l_first = BM_FACE_FIRST_LOOP(f);
 
@@ -224,7 +224,7 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
                         * while not all that nice, typically there are < 5 resulting faces,
                         * so its not _that_ bad. */
 
-                       STACK_INIT(face_split_arr);
+                       STACK_INIT(face_split_arr, STACK_SIZE(vert_split_arr));
                        STACK_PUSH(face_split_arr, f);
 
                        for (i = 0; i < STACK_SIZE(vert_split_arr) - 1; i++) {
index 14a6b631bd6d330c8d7bd96509a1a0a3b900f49f..95b0c37933ced52d221d133f0009ce0b7e4ff84b 100644 (file)
@@ -274,8 +274,8 @@ static DerivedMesh *applyModifier(
                            face_nors, true);
        }
 
-       STACK_INIT(new_vert_arr);
-       STACK_INIT(new_edge_arr);
+       STACK_INIT(new_vert_arr, numVerts * 2);
+       STACK_INIT(new_edge_arr, numEdges * 2);
 
        if (smd->flag & MOD_SOLIDIFY_RIM) {
                BLI_bitmap *orig_mvert_tag = BLI_BITMAP_NEW(numVerts, __func__);