From f32079d4b9f0ee565dc4bb63a4ef25286f183d0e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 29 Jun 2014 05:06:22 +1000 Subject: BLI_stackdefines Bounds check the stack while debugging, also add STACK_PEEK --- source/blender/blenkernel/intern/cdderivedmesh.c | 18 +++++----- source/blender/blenlib/BLI_stackdefines.h | 39 +++++++++++++++++----- source/blender/bmesh/intern/bmesh_core.c | 4 +-- source/blender/bmesh/intern/bmesh_queries.c | 8 ++--- source/blender/bmesh/operators/bmo_bisect_plane.c | 2 +- source/blender/bmesh/operators/bmo_connect.c | 4 +-- source/blender/bmesh/operators/bmo_removedoubles.c | 4 +-- .../bmesh/operators/bmo_subdivide_edgering.c | 4 +-- source/blender/bmesh/tools/bmesh_bisect_plane.c | 4 +-- source/blender/modifiers/intern/MOD_solidify.c | 4 +-- 10 files changed, 57 insertions(+), 34 deletions(-) diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 2d7e06c7308..3f8edbcf1be 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -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; diff --git a/source/blender/blenlib/BLI_stackdefines.h b/source/blender/blenlib/BLI_stackdefines.h index 3a4957599d6..24cb043cd43 100644 --- a/source/blender/blenlib/BLI_stackdefines.h +++ b/source/blender/blenlib/BLI_stackdefines.h @@ -23,20 +23,41 @@ /** \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 @@ -44,11 +65,13 @@ #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 diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index c4dc9909185..1c93eccf8bd 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -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); diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index d478ac07474..606e93d4a85 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -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) { diff --git a/source/blender/bmesh/operators/bmo_bisect_plane.c b/source/blender/bmesh/operators/bmo_bisect_plane.c index 378cf405e16..bed1ea5cb94 100644 --- a/source/blender/bmesh/operators/bmo_bisect_plane.c +++ b/source/blender/bmesh/operators/bmo_bisect_plane.c @@ -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) || diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index 8b0033a9342..4cf6e82fc8e 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -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) { diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c index a17ab2133c1..814649c7dbf 100644 --- a/source/blender/bmesh/operators/bmo_removedoubles.c +++ b/source/blender/bmesh/operators/bmo_removedoubles.c @@ -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; diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c index ae1ff5a7389..e13a9df4474 100644 --- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c +++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c @@ -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); diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.c b/source/blender/bmesh/tools/bmesh_bisect_plane.c index 0bd68e7a461..0ecb8066ac1 100644 --- a/source/blender/bmesh/tools/bmesh_bisect_plane.c +++ b/source/blender/bmesh/tools/bmesh_bisect_plane.c @@ -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++) { diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 14a6b631bd6..95b0c37933c 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -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__); -- cgit v1.2.3