commit f8e2cf9d7def06349b4726d5985123f08c3caf8d
parent 3a79b486935447c58da58a5060eb27b876f582dc
Author: vaplv <vaplv@free.fr>
Date: Tue, 19 Aug 2014 22:05:14 +0200
Fix memory area overlapping issues in the floatX[Y] functions
Diffstat:
| M | src/floatX.h | | | 84 | +++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------- |
| M | src/floatXY.h | | | 100 | +++++++++++++++++++++++++++++++++++++++++++------------------------------------ |
| M | src/rsys.h | | | 6 | ++++++ |
| M | src/str.c | | | 10 | ++-------- |
4 files changed, 119 insertions(+), 81 deletions(-)
diff --git a/src/floatX.h b/src/floatX.h
@@ -18,6 +18,9 @@ STATIC_ASSERT(FLOATX_DIMENSION__ > 1, Unexpected_value);
#define FLOATX_FUNC__(Func) \
CONCAT(CONCAT(CONCAT(f, FLOATX_DIMENSION__), _), Func)
+/* Helper macro */
+#define SIZEOF_FLOATX__ sizeof(float[FLOATX_DIMENSION__])
+
#if FLOATX_DIMENSION__ <= 4
static FINLINE float*
CONCAT(f, FLOATX_DIMENSION__)
@@ -56,15 +59,28 @@ FLOATX_FUNC__(splat)(float* dst, const float val)
}
static FINLINE float*
-FLOATX_FUNC__(set)(float* dst, const float* src)
+FLOATX_FUNC__(set__)(float* dst, const float* src)
{
int i;
ASSERT(dst && src);
+ ASSERT(!MEM_AREA_OVERLAP(dst, SIZEOF_FLOATX__, src, SIZEOF_FLOATX__));
FOR_EACH(i, 0, FLOATX_DIMENSION__)
dst[i] = src[i];
return dst;
}
+static FINLINE float*
+FLOATX_FUNC__(set)(float* dst, const float* src)
+{
+ ASSERT(dst && src);
+ if(!MEM_AREA_OVERLAP(dst, SIZEOF_FLOATX__, src, SIZEOF_FLOATX__)) {
+ return FLOATX_FUNC__(set__)(dst, src);
+ } else {
+ float tmp[FLOATX_DIMENSION__];
+ return FLOATX_FUNC__(set__)(dst, FLOATX_FUNC__(set__)(tmp, src));
+ }
+}
+
static FINLINE float
FLOATX_FUNC__(dot)(const float* a, const float* b)
{
@@ -86,6 +102,7 @@ FLOATX_FUNC__(len)(const float* a)
static FINLINE float
FLOATX_FUNC__(normalize)(float* dst, const float* a)
{
+ float tmp[FLOATX_DIMENSION__];
float len, rcp_len;
int i;
ASSERT(dst && a);
@@ -96,7 +113,8 @@ FLOATX_FUNC__(normalize)(float* dst, const float* a)
rcp_len = 1.0f / len;
FOR_EACH(i, 0, FLOATX_DIMENSION__)
- dst[i] = a[i] * rcp_len;
+ tmp[i] = a[i] * rcp_len;
+ FLOATX_FUNC__(set__)(dst, tmp);
return len;
}
@@ -109,91 +127,100 @@ FLOATX_FUNC__(is_normalized)(const float* a)
static FINLINE float*
FLOATX_FUNC__(add)(float* dst, const float* a, const float* b)
{
+ float tmp[FLOATX_DIMENSION__];
int i;
ASSERT(dst && a && b);
FOR_EACH(i, 0, FLOATX_DIMENSION__)
- dst[i] = a[i] + b[i];
- return dst;
+ tmp[i] = a[i] + b[i];
+ return FLOATX_FUNC__(set__)(dst, tmp);
}
static FINLINE float*
FLOATX_FUNC__(addf)(float* dst, const float* a, const float f)
{
+ float tmp[FLOATX_DIMENSION__];
int i;
ASSERT(dst && a);
FOR_EACH(i, 0, FLOATX_DIMENSION__)
- dst[i] = a[i] + f;
- return dst;
+ tmp[i] = a[i] + f;
+ return FLOATX_FUNC__(set__)(dst, tmp);
}
static FINLINE float*
FLOATX_FUNC__(sub)(float* dst, const float* a, const float* b)
{
+ float tmp[FLOATX_DIMENSION__];
int i;
ASSERT(dst && a && b);
FOR_EACH(i, 0, FLOATX_DIMENSION__)
- dst[i] = a[i] - b[i];
- return dst;
+ tmp[i] = a[i] - b[i];
+ return FLOATX_FUNC__(set__)(dst, tmp);
}
static FINLINE float*
FLOATX_FUNC__(subf)(float* dst, const float* a, const float f)
{
+ float tmp[FLOATX_DIMENSION__];
int i;
ASSERT(dst && a);
FOR_EACH(i, 0, FLOATX_DIMENSION__)
- dst[i] = a[i] - f;
- return dst;
+ tmp[i] = a[i] - f;
+ return FLOATX_FUNC__(set__)(dst, tmp);
}
static FINLINE float*
FLOATX_FUNC__(mul)(float* dst, const float* a, const float* b)
{
+ float tmp[FLOATX_DIMENSION__];
int i;
ASSERT(dst && a && b);
FOR_EACH(i, 0, FLOATX_DIMENSION__)
- dst[i] = a[i] * b[i];
- return dst;
+ tmp[i] = a[i] * b[i];
+ return FLOATX_FUNC__(set__)(dst, tmp);
}
static FINLINE float*
FLOATX_FUNC__(mulf)(float* dst, const float* a, const float f)
{
+ float tmp[FLOATX_DIMENSION__];
int i;
ASSERT(dst && a);
FOR_EACH(i, 0, FLOATX_DIMENSION__)
- dst[i] = a[i] * f;
- return dst;
+ tmp[i] = a[i] * f;
+ return FLOATX_FUNC__(set__)(dst, tmp);
}
static FINLINE float*
FLOATX_FUNC__(div)(float* dst, const float* a, const float* b)
{
+ float tmp[FLOATX_DIMENSION__];
int i;
ASSERT(dst && a && b);
FOR_EACH(i, 0, FLOATX_DIMENSION__)
- dst[i] = a[i] / b[i];
- return dst;
+ tmp[i] = a[i] / b[i];
+ return FLOATX_FUNC__(set__)(dst, tmp);
}
static FINLINE float*
FLOATX_FUNC__(divf)(float* dst, const float* a, const float f)
{
+ float tmp[FLOATX_DIMENSION__];
int i;
ASSERT(dst && a);
FOR_EACH(i, 0, FLOATX_DIMENSION__)
- dst[i] = a[i] / f;
- return dst;
+ tmp[i] = a[i] / f;
+ return FLOATX_FUNC__(set__)(dst, tmp);
}
static FINLINE float*
FLOATX_FUNC__(minus)(float* dst, const float* a)
{
+ float tmp[FLOATX_DIMENSION__];
int i;
ASSERT(dst && a);
FOR_EACH(i, 0, FLOATX_DIMENSION__)
- dst[i] = -a[i];
- return dst;
+ tmp[i] = -a[i];
+ return FLOATX_FUNC__(set__)(dst, tmp);
}
static FINLINE float
@@ -222,10 +249,11 @@ FLOATX_FUNC__(lerp)
} else if(t >= 1.0f) {
FLOATX_FUNC__(set)(dst, to);
} else {
+ float tmp[FLOATX_DIMENSION__];
int i;
- FOR_EACH(i, 0, FLOATX_DIMENSION__) {
- dst[i] = from[i] + t * (to[i] - from[i]);
- }
+ FOR_EACH(i, 0, FLOATX_DIMENSION__)
+ tmp[i] = from[i] + t * (to[i] - from[i]);
+ FLOATX_FUNC__(set__)(dst, tmp);
}
return dst;
}
@@ -259,21 +287,23 @@ FLOATX_FUNC__(eq_eps)(const float* a, const float* b, const float eps)
static FINLINE float*
FLOATX_FUNC__(max)(float* dst, const float* a, const float* b)
{
+ float tmp[FLOATX_DIMENSION__];
int i;
ASSERT(dst && a && b);
FOR_EACH(i, 0, FLOATX_DIMENSION__)
- dst[i] = a[i] > b[i] ? a[i] : b[i];
- return dst;
+ tmp[i] = a[i] > b[i] ? a[i] : b[i];
+ return FLOATX_FUNC__(set__)(dst, tmp);
}
static FINLINE float*
FLOATX_FUNC__(min)(float* dst, const float* a, const float* b)
{
+ float tmp[FLOATX_DIMENSION__];
int i;
ASSERT(dst && a && b);
FOR_EACH(i, 0, FLOATX_DIMENSION__)
- dst[i] = a[i] < b[i] ? a[i] : b[i];
- return dst;
+ tmp[i] = a[i] < b[i] ? a[i] : b[i];
+ return FLOATX_FUNC__(set__)(dst, tmp);
}
#undef FLOATX_DIMENSION__
diff --git a/src/floatXY.h b/src/floatXY.h
@@ -25,6 +25,9 @@ STATIC_ASSERT
#define FLOATY_FUNC__(Func) \
CONCAT(CONCAT(CONCAT(f, FLOATY_DIMENSION__), _), Func)
+/* Helper macro */
+#define SIZEOF_FLOATXY__ sizeof(float[FLOATX_DIMENSION__*FLOATY_DIMENSION__])
+
static FINLINE float*
FLOATXY_FUNC__(splat)(float* dst, const float val)
{
@@ -37,32 +40,43 @@ FLOATXY_FUNC__(splat)(float* dst, const float val)
}
static FINLINE float*
-FLOATXY_FUNC__(set)(float* dst, const float* src)
+FLOATXY_FUNC__(set__)(float* dst, const float* src)
{
int x, y, i;
ASSERT(dst && src);
+ ASSERT(!MEM_AREA_OVERLAP(dst, SIZEOF_FLOATXY__, src, SIZEOF_FLOATXY__));
i = 0;
FOR_EACH(x, 0, FLOATX_DIMENSION__) {
- FOR_EACH(y, 0, FLOATY_DIMENSION__) {
- dst[i] = src[i];
- ++i;
- }
- }
+ FOR_EACH(y, 0, FLOATY_DIMENSION__) {
+ dst[i] = src[i];
+ ++i;
+ }}
return dst;
}
static FINLINE float*
+FLOATXY_FUNC__(set)(float* dst, const float* src)
+{
+ ASSERT(dst && src);
+ if(!MEM_AREA_OVERLAP(dst, SIZEOF_FLOATXY__, src, SIZEOF_FLOATXY__)) {
+ return FLOATXY_FUNC__(set__)(dst, src);
+ } else {
+ float tmp[FLOATX_DIMENSION__*FLOATY_DIMENSION__];
+ return FLOATXY_FUNC__(set__)(dst, FLOATXY_FUNC__(set__)(tmp, src));
+ }
+}
+
+static FINLINE float*
FLOATXY_FUNC__(set_identity)(float* mat)
{
int x, y, i;
ASSERT(mat);
i = 0;
FOR_EACH(x, 0, FLOATX_DIMENSION__) {
- FOR_EACH(y, 0, FLOATY_DIMENSION__) {
- mat[i] = x == y ? 1.f : 0.f;
- ++i;
- }
- }
+ FOR_EACH(y, 0, FLOATY_DIMENSION__) {
+ mat[i] = x == y ? 1.f : 0.f;
+ ++i;
+ }}
return mat;
}
@@ -138,28 +152,31 @@ FLOATXY_FUNC__(col)(float* col, const float* mat, const int icol)
static FINLINE float*
FLOATXY_FUNC__(add)(float* dst, const float* a, const float* b)
{
+ float tmp[FLOATX_DIMENSION__*FLOATY_DIMENSION__];
int i;
FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__)
- dst[i] = a[i] + b[i];
- return dst;
+ tmp[i] = a[i] + b[i];
+ return FLOATXY_FUNC__(set__)(dst, tmp);
}
static FINLINE float*
FLOATXY_FUNC__(sub)(float* dst, const float* a, const float* b)
{
+ float tmp[FLOATX_DIMENSION__*FLOATY_DIMENSION__];
int i;
FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__)
- dst[i] = a[i] - b[i];
- return dst;
+ tmp[i] = a[i] - b[i];
+ return FLOATXY_FUNC__(set__)(dst, tmp);
}
static FINLINE float*
FLOATXY_FUNC__(minus)(float* dst, const float* a)
{
+ float tmp[FLOATX_DIMENSION__*FLOATY_DIMENSION__];
int i;
FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__)
- dst[i] = -a[i];
- return dst;
+ tmp[i] = -a[i];
+ return FLOATXY_FUNC__(set__)(dst, tmp);
}
static FINLINE char
@@ -211,12 +228,12 @@ FLOATXY_FUNC__(CONCAT(mulf, FLOATX_DIMENSION__))
static FINLINE float*
FLOATXY_FUNC__(mul)(float* dst, const float* mat, const float b)
{
+ float tmp[FLOATX_DIMENSION__*FLOATY_DIMENSION__];
int i;
ASSERT(dst && mat);
- FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__) {
- dst[i] = mat[i] * b;
- }
- return dst;
+ FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__)
+ tmp[i] = mat[i] * b;
+ return FLOATXY_FUNC__(set__)(dst, tmp);;
}
static FINLINE float*
@@ -243,15 +260,11 @@ FLOATXY_FUNC__(transpose)(float* dst, const float* src)
i = 0;
FOR_EACH(x, 0, FLOATX_DIMENSION__) {
- FOR_EACH(y, 0, FLOATY_DIMENSION__) {
- tmp[y * FLOATY_DIMENSION__ + x] = src[i];
- ++i;
- }
- }
- FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__) {
- dst[i] = tmp[i];
- }
- return dst;
+ FOR_EACH(y, 0, FLOATY_DIMENSION__) {
+ tmp[y * FLOATY_DIMENSION__ + x] = src[i];
+ ++i;
+ }}
+ return FLOATXY_FUNC__(set__)(dst, tmp);
}
static FINLINE float*
@@ -265,25 +278,19 @@ FLOATXY_FUNC__(CONCAT(CONCAT(mulf, FLOATX_DIMENSION__), FLOATY_DIMENSION__))
/* Transpose the a matrix */
i = 0;
FOR_EACH(x, 0, FLOATX_DIMENSION__) {
- FOR_EACH(y, 0, FLOATY_DIMENSION__) {
- a_trans[y * FLOATY_DIMENSION__ + x] = a[i];
- ++i;
- }
- }
+ FOR_EACH(y, 0, FLOATY_DIMENSION__) {
+ a_trans[y * FLOATY_DIMENSION__ + x] = a[i];
+ ++i;
+ }}
/* Compute the a x b and store the result into tmp */
i = 0;
FOR_EACH(x, 0, FLOATX_DIMENSION__) {
- FOR_EACH(y, 0, FLOATY_DIMENSION__) {
- tmp[i] = FLOATX_FUNC__(dot)
- (a_trans + (y * FLOATY_DIMENSION__), b + (x * FLOATY_DIMENSION__));
- ++i;
- }
- }
- /* Copy the tmp matrix into dst */
- FOR_EACH(i, 0, FLOATX_DIMENSION__ * FLOATY_DIMENSION__) {
- dst[i] = tmp[i];
- }
- return dst;
+ FOR_EACH(y, 0, FLOATY_DIMENSION__) {
+ tmp[i] = FLOATX_FUNC__(dot)
+ (a_trans + (y * FLOATY_DIMENSION__), b + (x * FLOATY_DIMENSION__));
+ ++i;
+ }}
+ return FLOATXY_FUNC__(set__)(dst, tmp);
}
#endif /* FLOATX_DIMENSION__ == FLOATY_DIMENSION__ */
@@ -291,4 +298,5 @@ FLOATXY_FUNC__(CONCAT(CONCAT(mulf, FLOATX_DIMENSION__), FLOATY_DIMENSION__))
#undef FLOATXY_FUNC__
#undef FLOATX_DIMENSION__
#undef FLOATY_DIMENSION__
+#undef SIZEOF_FLOATXY__
diff --git a/src/rsys.h b/src/rsys.h
@@ -206,6 +206,12 @@
#define OFFSET_PTR(Ptr, Offset) (void*)((uintptr_t)(Ptr) + (Offset))
+#define MEM_AREA_OVERLAP( A, SzA, B, SzB ) \
+ (((uintptr_t)(A) >= (uintptr_t)(B) && \
+ (uintptr_t)(A) < ((uintptr_t)(B) + (SzB))) || \
+ (((uintptr_t)(A) + (SzA)) >= (uintptr_t)(B) && \
+ ((uintptr_t)(A) + (SzA)) < ((uintptr_t)(B) + (SzB))))
+
#ifdef __cplusplus
#define BEGIN_DECLS extern "C" {
#define END_DECLS }
diff --git a/src/str.c b/src/str.c
@@ -1,12 +1,6 @@
#include "str.h"
#include <string.h>
-#define IS_MEMORY_OVERLAPPED__( A, SzA, B, SzB ) \
- (((uintptr_t)(A) >= (uintptr_t)(B) && \
- (uintptr_t)(A) < ((uintptr_t)(B) + (SzB))) || \
- (((uintptr_t)(A) + (SzA)) >= (uintptr_t)(B) && \
- ((uintptr_t)(A) + (SzA)) < ((uintptr_t)(B) + (SzB))))
-
/*******************************************************************************
* helper function
******************************************************************************/
@@ -71,7 +65,7 @@ str_insert(struct str* str, const size_t i, const char* cstr)
return -1 ;
cstr_len = strlen(cstr);
- ASSERT(!IS_MEMORY_OVERLAPPED__
+ ASSERT(!MEM_AREA_OVERLAP
(str->cstr, str->allocated, cstr, (cstr_len + 1) * sizeof(char)));
if(i == str->len) {
@@ -125,7 +119,7 @@ str_append(struct str* str, const char* cstr)
ASSERT(str && cstr);
cstr_len = strlen(cstr);
- ASSERT(!IS_MEMORY_OVERLAPPED__
+ ASSERT(!MEM_AREA_OVERLAP
(str->cstr, str->allocated, cstr, (cstr_len + 1) * sizeof(char)));
res = ensure_allocated(str, cstr_len + str->len + 1, 1);