[PATCH wayland] make wl_fixed_t a safe type
Pekka Paalanen
ppaalanen at gmail.com
Mon Jun 4 07:48:16 PDT 2012
Turn wl_fixed_t into a struct type, so that it will no longer implicitly
cast into any other type.
Silent implicit casts between wl_fixed_t and all integer types have
hidden many bugs, that the compiler could have easily cought.
Signed-off-by: Pekka Paalanen <ppaalanen at gmail.com>
---
src/connection.c | 7 ++++---
src/wayland-util.h | 39 +++++++++++++++++++++++++++++++--------
tests/connection-test.c | 19 ++++++++++---------
tests/fixed-benchmark.c | 14 +++++++-------
tests/fixed-test.c | 42 +++++++++++++++++++++---------------------
5 files changed, 73 insertions(+), 48 deletions(-)
diff --git a/src/connection.c b/src/connection.c
index 5b7965e..dce22d4 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -434,7 +434,7 @@ wl_closure_vmarshal(struct wl_closure *closure,
closure->args[i] = p;
if (end - p < 1)
goto err;
- *p++ = va_arg(ap, wl_fixed_t);
+ *p++ = (va_arg(ap, wl_fixed_t)).raw;
break;
case 'u':
closure->types[i] = &ffi_type_uint32;
@@ -825,6 +825,7 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
{
union wl_value *value;
int32_t si;
+ wl_fixed_t fixed;
int i;
struct timespec tp;
unsigned int time;
@@ -852,8 +853,8 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
fprintf(stderr, "%d", si);
break;
case 'f':
- si = (int32_t) value->uint32;
- fprintf(stderr, "%f", wl_fixed_to_double(si));
+ fixed.raw = (int32_t) value->uint32;
+ fprintf(stderr, "%f", wl_fixed_to_double(fixed));
break;
case 's':
fprintf(stderr, "\"%s\"", value->string);
diff --git a/src/wayland-util.h b/src/wayland-util.h
index 8447640..b3495fe 100644
--- a/src/wayland-util.h
+++ b/src/wayland-util.h
@@ -167,17 +167,19 @@ void wl_array_release(struct wl_array *array);
void *wl_array_add(struct wl_array *array, size_t size);
void wl_array_copy(struct wl_array *array, struct wl_array *source);
-typedef int32_t wl_fixed_t;
+typedef struct {
+ int32_t raw;
+} wl_fixed_t;
static inline double
-wl_fixed_to_double (wl_fixed_t f)
+wl_fixed_to_double(wl_fixed_t f)
{
union {
double d;
int64_t i;
} u;
- u.i = ((1023LL + 44LL) << 52) + (1LL << 51) + f;
+ u.i = ((1023LL + 44LL) << 52) + (1LL << 51) + f.raw;
return u.d - (3LL << 43);
}
@@ -185,23 +187,44 @@ wl_fixed_to_double (wl_fixed_t f)
static inline wl_fixed_t
wl_fixed_from_double(double d)
{
+ wl_fixed_t f;
union {
double d;
int64_t i;
} u;
u.d = d + (3LL << (51 - 8));
+ f.raw = u.i;
- return u.i;
+ return f;
}
-static inline int wl_fixed_to_int(wl_fixed_t f)
+static inline int
+wl_fixed_to_int(wl_fixed_t f)
{
- return f / 256;
+ return f.raw / 256;
}
-static inline wl_fixed_t wl_fixed_from_int(int i)
+
+static inline wl_fixed_t
+wl_fixed_from_int(int i)
+{
+ wl_fixed_t f;
+ f.raw = i * 256;
+ return f;
+}
+
+static inline wl_fixed_t
+wl_fixed_add(wl_fixed_t a, wl_fixed_t b)
+{
+ wl_fixed_t result = { a.raw + b.raw };
+ return result;
+}
+
+static inline wl_fixed_t
+wl_fixed_sub(wl_fixed_t a, wl_fixed_t b)
{
- return i * 256;
+ wl_fixed_t result = { a.raw - b.raw };
+ return result;
}
typedef void (*wl_log_func_t)(const char *, va_list);
diff --git a/tests/connection-test.c b/tests/connection-test.c
index 14a58e6..b219981 100644
--- a/tests/connection-test.c
+++ b/tests/connection-test.c
@@ -152,6 +152,7 @@ struct marshal_data {
union {
uint32_t u;
int32_t i;
+ wl_fixed_t f;
const char *s;
int h;
} value;
@@ -292,7 +293,7 @@ static void
validate_demarshal_f(struct marshal_data *data,
struct wl_object *object, wl_fixed_t f)
{
- assert(data->value.i == f);
+ assert(data->value.f.raw == f.raw);
}
static void
@@ -343,10 +344,10 @@ TEST(connection_demarshal)
memcpy(&msg[3], data.value.s, msg[2]);
demarshal(&data, "s", msg, (void *) validate_demarshal_s);
- data.value.i = wl_fixed_from_double(-90000.2390);
+ data.value.f = wl_fixed_from_double(-90000.2390);
msg[0] = 400200;
msg[1] = 12;
- msg[2] = data.value.i;
+ msg[2] = data.value.f.raw;
demarshal(&data, "f", msg, (void *) validate_demarshal_f);
release_marshal_data(&data);
@@ -414,17 +415,17 @@ TEST(connection_marshal_demarshal)
marshal_demarshal(&data, (void *) validate_demarshal_h,
8, "h", data.value.h);
- data.value.i = wl_fixed_from_double(1234.5678);
+ data.value.f = wl_fixed_from_double(1234.5678);
marshal_demarshal(&data, (void *) validate_demarshal_f,
- 12, "f", data.value.i);
+ 12, "f", data.value.f);
- data.value.i = wl_fixed_from_double(-90000.2390);
+ data.value.f = wl_fixed_from_double(-90000.2390);
marshal_demarshal(&data, (void *) validate_demarshal_f,
- 12, "f", data.value.i);
+ 12, "f", data.value.f);
- data.value.i = wl_fixed_from_double((1 << 23) - 1 + 0.0941);
+ data.value.f = wl_fixed_from_double((1 << 23) - 1 + 0.0941);
marshal_demarshal(&data, (void *) validate_demarshal_f,
- 12, "f", data.value.i);
+ 12, "f", data.value.f);
release_marshal_data(&data);
}
diff --git a/tests/fixed-benchmark.c b/tests/fixed-benchmark.c
index 0d7abd0..9374c65 100644
--- a/tests/fixed-benchmark.c
+++ b/tests/fixed-benchmark.c
@@ -38,8 +38,8 @@ noop_conversion(void)
double d;
} u;
- for (f = 0; f < INT32_MAX; f++) {
- u.i = f;
+ for (f.raw = 0; f.raw < INT32_MAX; f.raw++) {
+ u.i = f.raw;
global_d = u.d;
}
}
@@ -49,7 +49,7 @@ magic_conversion(void)
{
wl_fixed_t f;
- for (f = 0; f < INT32_MAX; f++)
+ for (f.raw = 0; f.raw < INT32_MAX; f.raw++)
global_d = wl_fixed_to_double(f);
}
@@ -59,8 +59,8 @@ mul_conversion(void)
wl_fixed_t f;
/* This will get optimized into multiplication by 1/256 */
- for (f = 0; f < INT32_MAX; f++)
- global_d = f / 256.0;
+ for (f.raw = 0; f.raw < INT32_MAX; f.raw++)
+ global_d = f.raw / 256.0;
}
double factor = 256.0;
@@ -70,8 +70,8 @@ div_conversion(void)
{
wl_fixed_t f;
- for (f = 0; f < INT32_MAX; f++)
- global_d = f / factor;
+ for (f.raw = 0; f.raw < INT32_MAX; f.raw++)
+ global_d = f.raw / factor;
}
static void
diff --git a/tests/fixed-test.c b/tests/fixed-test.c
index 16fa5ff..76955ba 100644
--- a/tests/fixed-test.c
+++ b/tests/fixed-test.c
@@ -33,38 +33,38 @@ TEST(fixed_double_conversions)
d = 62.125;
f = wl_fixed_from_double(d);
- fprintf(stderr, "double %lf to fixed %x\n", d, f);
- assert(f == 0x3e20);
+ fprintf(stderr, "double %lf to fixed %x\n", d, f.raw);
+ assert(f.raw == 0x3e20);
d = -1200.625;
f = wl_fixed_from_double(d);
- fprintf(stderr, "double %lf to fixed %x\n", d, f);
- assert(f == -0x4b0a0);
+ fprintf(stderr, "double %lf to fixed %x\n", d, f.raw);
+ assert(f.raw == -0x4b0a0);
- f = random();
+ f.raw = random();
d = wl_fixed_to_double(f);
- fprintf(stderr, "fixed %x to double %lf\n", f, d);
- assert(d == f / 256.0);
+ fprintf(stderr, "fixed %x to double %lf\n", f.raw, d);
+ assert(d == f.raw / 256.0);
- f = 0x012030;
+ f.raw = 0x012030;
d = wl_fixed_to_double(f);
- fprintf(stderr, "fixed %x to double %lf\n", f, d);
+ fprintf(stderr, "fixed %x to double %lf\n", f.raw, d);
assert(d == 288.1875);
- f = 0x70000000;
+ f.raw = 0x70000000;
d = wl_fixed_to_double(f);
- fprintf(stderr, "fixed %x to double %lf\n", f, d);
- assert(d == f / 256);
+ fprintf(stderr, "fixed %x to double %lf\n", f.raw, d);
+ assert(d == f.raw / 256);
- f = -0x012030;
+ f.raw = -0x012030;
d = wl_fixed_to_double(f);
- fprintf(stderr, "fixed %x to double %lf\n", f, d);
+ fprintf(stderr, "fixed %x to double %lf\n", f.raw, d);
assert(d == -288.1875);
- f = 0x80000000;
+ f.raw = 0x80000000;
d = wl_fixed_to_double(f);
- fprintf(stderr, "fixed %x to double %lf\n", f, d);
- assert(d == f / 256);
+ fprintf(stderr, "fixed %x to double %lf\n", f.raw, d);
+ assert(d == f.raw / 256);
}
TEST(fixed_int_conversions)
@@ -74,17 +74,17 @@ TEST(fixed_int_conversions)
i = 62;
f = wl_fixed_from_int(i);
- assert(f == 62 * 256);
+ assert(f.raw == 62 * 256);
i = -2080;
f = wl_fixed_from_int(i);
- assert(f == -2080 * 256);
+ assert(f.raw == -2080 * 256);
- f = 0x277013;
+ f.raw = 0x277013;
i = wl_fixed_to_int(f);
assert(i == 0x2770);
- f = -0x5044;
+ f.raw = -0x5044;
i = wl_fixed_to_int(f);
assert(i == -0x50);
}
--
1.7.3.4
More information about the wayland-devel
mailing list