Relanding: Add CAIRO_ENSURE_UNIQUE macro and use it in _cairo_error()

When using MSVC, _cairo_error() can be folded into other identical functions.
If that happens, _cairo_error isn't really useful anymore. Using the
CAIRO_ENSURE_UNIQUE macro makes sure this doesn't happen.

Use __asm to serve as a line delimiter. This allows us to use the
__asm{} block in a macro.
This commit is contained in:
Jeff Muizelaar 2009-02-19 16:00:17 -05:00
parent 78de0e045e
commit fe7d5323f5
2 changed files with 25 additions and 0 deletions

View file

@ -172,6 +172,30 @@
#define inline __inline
#endif
#ifdef _MSC_VER
/* When compiling with /Gy and /OPT:ICF identical functions will be folded in together.
The CAIRO_ENSURE_UNIQUE macro ensures that a function is always unique and
will never be folded into another one. Something like this might eventually
be needed for GCC but it seems fine for now. */
#define CAIRO_ENSURE_UNIQUE \
do { \
char func[] = __FUNCTION__; \
char file[] = __FILE__; \
__asm { \
__asm jmp __internal_skip_line_no \
__asm _emit (__LINE__ & 0xff) \
__asm _emit ((__LINE__>>8) & 0xff) \
__asm _emit ((__LINE__>>16) & 0xff) \
__asm _emit ((__LINE__>>24) & 0xff) \
__asm lea eax, func \
__asm lea eax, file \
__asm __internal_skip_line_no: \
}; \
} while (0)
#else
#define CAIRO_ENSURE_UNIQUE do { } while (0)
#endif
#ifdef __STRICT_ANSI__
#undef inline
#define inline __inline__

View file

@ -82,6 +82,7 @@ static const cairo_t _cairo_nil = {
cairo_status_t
_cairo_error (cairo_status_t status)
{
CAIRO_ENSURE_UNIQUE;
assert (_cairo_status_is_error (status));
return status;