[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 47/55: Reimplement SCM_MAKE_CHAR to evaluate its argumen
From: |
Andy Wingo |
Subject: |
[Guile-commits] 47/55: Reimplement SCM_MAKE_CHAR to evaluate its argument only once. |
Date: |
Thu, 23 May 2019 11:52:44 -0400 (EDT) |
wingo pushed a commit to branch master
in repository guile.
commit 7e208c8f256ac4d7ef670655aa42711433fdd781
Author: Mark H Weaver <address@hidden>
Date: Tue Apr 16 23:11:42 2019 -0400
Reimplement SCM_MAKE_CHAR to evaluate its argument only once.
The motivation for this change is that SCM_MAKE_CHAR is sometimes passed
an expression that involves a procedure call that is not always trivial.
In other cases, the results are not guaranteed to be the same both
times, which could lead to the creation of invalid SCM objects.
* libguile/chars.h (SCM_MAKE_CHAR): Reimplement.
---
libguile/chars.h | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/libguile/chars.h b/libguile/chars.h
index e628b40..8cf8a11 100644
--- a/libguile/chars.h
+++ b/libguile/chars.h
@@ -1,7 +1,7 @@
#ifndef SCM_CHARS_H
#define SCM_CHARS_H
-/* Copyright 1995-1996,2000-2001,2004,2006,2008-2009,2018
+/* Copyright 1995-1996,2000-2001,2004,2006,2008-2009,2018-2019
Free Software Foundation, Inc.
This file is part of Guile.
@@ -30,16 +30,18 @@
#define SCM_CHARP(x) (SCM_ITAG8(x) == scm_tc8_char)
#define SCM_CHAR(x) ((scm_t_wchar)SCM_ITAG8_DATA(x))
-/* SCM_MAKE_CHAR maps signed chars (-128 to 127) and unsigned chars (0
- to 255) to Latin-1 codepoints (0 to 255) while allowing higher
+/* SCM_MAKE_CHAR maps signed chars (-128 to 127) and unsigned chars
+ (0 to 255) to Latin-1 codepoints (0 to 255) while allowing higher
codepoints (256 to 1114111) to pass through unchanged.
- This macro evaluates x twice, which may lead to side effects if not
- used properly. */
-#define SCM_MAKE_CHAR(x) \
- ((x) <= 1 \
- ? SCM_MAKE_ITAG8 ((scm_t_bits) (unsigned char) (x), scm_tc8_char) \
- : SCM_MAKE_ITAG8 ((scm_t_bits) (x), scm_tc8_char))
+ To avoid evaluating X more than once, we use an arithmetic trick: we
+ compute (X mod 2^N) mod (2^N - 256), which is equal to the required
+ mapping in the range -256 .. (2^N - 257). Here, N is the number of
+ bits in scm_t_bits. Note that (scm_t_bits) (x) implicitly computes
+ (X mod 2^N), and (scm_t_bits) -256 equals (2^N - 256). GCC is able
+ to optimize away these operations in practice. */
+#define SCM_MAKE_CHAR(x) \
+ (SCM_MAKE_ITAG8 ((scm_t_bits) (x) % (scm_t_bits) -256, scm_tc8_char))
#define SCM_CODEPOINT_DOTTED_CIRCLE (0x25cc)
#define SCM_CODEPOINT_SURROGATE_START (0xd800)
- [Guile-commits] 31/55: Support ~N in SRFI-19 string->date, (continued)
- [Guile-commits] 31/55: Support ~N in SRFI-19 string->date, Andy Wingo, 2019/05/23
- [Guile-commits] 28/55: Documentation fixes, Andy Wingo, 2019/05/23
- [Guile-commits] 42/55: Disable test for current value of setitimer on Cygwin, Andy Wingo, 2019/05/23
- [Guile-commits] 29/55: Fix spelling of ellipsis in (ice-9 match)., Andy Wingo, 2019/05/23
- [Guile-commits] 53/55: put-u8: Always write a single byte, regardless of the port encoding., Andy Wingo, 2019/05/23
- [Guile-commits] 52/55: Optimize fixnum exact integer square roots., Andy Wingo, 2019/05/23
- [Guile-commits] 44/55: Avoid passing NULL to 'memcpy' and 'memcmp'., Andy Wingo, 2019/05/23
- [Guile-commits] 14/55: Fix typos, indentation and error reporting in SRFI-19., Andy Wingo, 2019/05/23
- [Guile-commits] 54/55: Strings, i18n: Limit the use of alloca to approximately 8 kilobytes., Andy Wingo, 2019/05/23
- [Guile-commits] 49/55: Fix typo in comment., Andy Wingo, 2019/05/23
- [Guile-commits] 47/55: Reimplement SCM_MAKE_CHAR to evaluate its argument only once.,
Andy Wingo <=
- [Guile-commits] 51/55: Avoid 'with-latin1-locale' in binary I/O tests., Andy Wingo, 2019/05/23
- [Guile-commits] 15/55: Use 'scm_from_utf8_{string, symbol, keyword}' for C string literals., Andy Wingo, 2019/05/23
- [Guile-commits] 23/55: SRFI-19: Check for incompatible types in time comparisons., Andy Wingo, 2019/05/23
- [Guile-commits] 34/55: Don't mutate read-only string in ports test, Andy Wingo, 2019/05/23
- [Guile-commits] 36/55: Fix strftime compile with null threads, Andy Wingo, 2019/05/23
- [Guile-commits] 25/55: SRFI-19: Minor refactor of leap second table lookups., Andy Wingo, 2019/05/23
- [Guile-commits] 45/55: Update user-visible copyright years., Andy Wingo, 2019/05/23
- [Guile-commits] 46/55: Fix gc.test "after-gc-hook gets called" failures., Andy Wingo, 2019/05/23
- [Guile-commits] 55/55: Update iconv.m4 from gnulib., Andy Wingo, 2019/05/23
- [Guile-commits] 50/55: Fix indentation in scm_sum., Andy Wingo, 2019/05/23