Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,17 @@ if(ABC_USE_NAMESPACE)
set_source_files_properties(${ABC_SRC} PROPERTIES LANGUAGE CXX)
endif()

# Allocation failures cross ABC's C frames on their way to STP's handler.
# C++ unwinding needs exception tables even in translation units with no
# cleanup of their own.
list(APPEND ABC_SRC src/misc/util/utilAlloc.cpp)

function(abc_properties target visibility)
target_include_directories(${target} ${visibility} ${CMAKE_CURRENT_SOURCE_DIR}/src )
target_compile_options_filtered(${target} ${visibility} ${ABC_CFLAGS} ${ABC_CXXFLAGS} -Wno-unused-but-set-variable )
if(NOT MSVC)
target_compile_options(${target} PRIVATE -fexceptions)
endif()
target_link_libraries(${target} ${visibility} ${ABC_LIBS})
endfunction()

Expand Down
43 changes: 38 additions & 5 deletions src/misc/util/abc_global.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,46 @@ typedef ABC_INT64_T iword;
#define ABC_PRMn(a,f) (Abc_Print(1, "%s =", (a)), Abc_Print(1, "%10.3f MB ", 1.0*((double)(f))/(1<<20)))
#define ABC_PRMP(a,f,F) (Abc_Print(1, "%s =", (a)), Abc_Print(1, "%10.3f MB (%6.2f %%)\n", (1.0*((double)(f))/(1<<20)), (((double)(F))? 100.0*((double)(f))/((double)(F)) : 0.0) ) )

#define ABC_ALLOC(type, num) ((type *) malloc(sizeof(type) * (size_t)(num)))
#define ABC_CALLOC(type, num) ((type *) calloc((size_t)(num), sizeof(type)))
#define ABC_FALLOC(type, num) ((type *) memset(malloc(sizeof(type) * (size_t)(num)), 0xff, sizeof(type) * (size_t)(num)))
/* STP catches allocation failure at its C++ API boundary. Never publish a
* null buffer to ABC's callers, which assume allocation succeeded. */
#define ABC_STP_CHECKED_ALLOCATIONS 1
extern void Abc_ThrowBadAlloc( void );

static inline size_t Abc_AllocSize( size_t size, size_t count )
{
if ( count && size > (size_t)-1 / count )
Abc_ThrowBadAlloc();
return size * count;
}
static inline void * Abc_AllocMemory( size_t size )
{
void * result = malloc( size ? size : 1 );
if ( !result )
Abc_ThrowBadAlloc();
return result;
}
static inline void * Abc_CallocMemory( size_t size, size_t count )
{
size_t bytes = Abc_AllocSize( size, count );
void * result = calloc( bytes ? bytes : 1, 1 );
if ( !result )
Abc_ThrowBadAlloc();
return result;
}
static inline void * Abc_ReallocMemory( void * ptr, size_t size )
{
void * result = realloc( ptr, size ? size : 1 );
if ( !result )
Abc_ThrowBadAlloc();
return result;
}

#define ABC_ALLOC(type, num) ((type *) Abc_AllocMemory(Abc_AllocSize(sizeof(type), (size_t)(num))))
#define ABC_CALLOC(type, num) ((type *) Abc_CallocMemory(sizeof(type), (size_t)(num)))
#define ABC_FALLOC(type, num) ((type *) memset(ABC_ALLOC(type, num), 0xff, Abc_AllocSize(sizeof(type), (size_t)(num))))
#define ABC_FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
#define ABC_REALLOC(type, obj, num) \
((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (size_t)(num))) : \
((type *) malloc(sizeof(type) * (size_t)(num))))
((type *) Abc_ReallocMemory((void *)(obj), Abc_AllocSize(sizeof(type), (size_t)(num))))

static inline int Abc_AbsInt( int a ) { return a < 0 ? -a : a; }
static inline int Abc_MaxInt( int a, int b ) { return a > b ? a : b; }
Expand Down
13 changes: 13 additions & 0 deletions src/misc/util/utilAlloc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// ABC's checked C allocation helpers report exhaustion to the embedding
// C++ caller. Keep the throw here so ABC itself can still be compiled as C.
#include <new>
#include "misc/util/abc_global.h"

ABC_NAMESPACE_IMPL_START

void Abc_ThrowBadAlloc( void )
{
throw std::bad_alloc();
}

ABC_NAMESPACE_IMPL_END
Loading