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 <[email protected]> --- 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 _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
