diff --git a/include/chibi/features.h b/include/chibi/features.h index ece95ccd..e5e412ea 100644 --- a/include/chibi/features.h +++ b/include/chibi/features.h @@ -86,6 +86,21 @@ /* uncomment this to add very verbose debugging stats to the native GC */ /* #define SEXP_USE_DEBUG_GC 1 */ +/* uncomment this to enable "safe" field accessors for primitive types */ +/* The sexp union type fields are abstracted away with macros of the */ +/* form sexp__(), however these are just convenience */ +/* macros equivalent to directly accessing the union field, and will */ +/* return incorrect results (or segfault) if isn't of the correct */ +/* . Thus you're required to check the types manually before */ +/* accessing them. However, to detect errors earlier you can enable */ +/* SEXP_USE_SAFE_ACCESSORS, and on invalid accesses chibi will print */ +/* a friendly error message and immediately segfault itself so you */ +/* can see where the invalid access was made. */ +/* Note this is only intended for debugging, and mostly for user code. */ +/* If you want to build chibi itself with this option, compilation */ +/* may be very slow and using CFLAGS=-O0 is recommended. */ +/* #define SEXP_USE_SAFE_ACCESSORS 1 */ + /* uncomment this to make the heap common to all contexts */ /* By default separate contexts can have separate heaps, */ /* and are thus thread-safe and independant. */ diff --git a/include/chibi/sexp.h b/include/chibi/sexp.h index 72535f6e..81092cbe 100755 --- a/include/chibi/sexp.h +++ b/include/chibi/sexp.h @@ -845,8 +845,8 @@ SEXP_API sexp sexp_make_unsigned_integer(sexp ctx, sexp_luint_t x); #define sexp_string_ref(x, i) (sexp_make_character((unsigned char)sexp_string_data(x)[sexp_unbox_fixnum(i)])) #define sexp_string_set(x, i, v) (sexp_string_data(x)[sexp_unbox_fixnum(i)] = sexp_unbox_character(v)) -#define sexp_symbol_data(x) (sexp_field(x, symbol, SEXP_SYMBOL, data)) -#define sexp_symbol_length(x) (sexp_field(x, symbol, SEXP_SYMBOL, length)) +#define sexp_lsymbol_data(x) (sexp_field(x, symbol, SEXP_SYMBOL, data)) +#define sexp_lsymbol_length(x) (sexp_field(x, symbol, SEXP_SYMBOL, length)) #define sexp_port_stream(p) (sexp_pred_field(p, port, sexp_portp, stream)) #define sexp_port_name(p) (sexp_pred_field(p, port, sexp_portp, name)) diff --git a/lib/srfi/95/qsort.c b/lib/srfi/95/qsort.c index 13810918..6bafd978 100644 --- a/lib/srfi/95/qsort.c +++ b/lib/srfi/95/qsort.c @@ -82,7 +82,7 @@ static int sexp_object_compare (sexp ctx, sexp a, sexp b) { res = strcmp(sexp_string_data(a), sexp_string_data(b)); break; case SEXP_SYMBOL: - res = strcmp(sexp_symbol_data(a), sexp_symbol_data(b)); + res = strcmp(sexp_lsymbol_data(a), sexp_lsymbol_data(b)); break; default: res = 0; @@ -91,7 +91,7 @@ static int sexp_object_compare (sexp ctx, sexp a, sexp b) { } #if SEXP_USE_HUFF_SYMS } else if (sexp_lsymbolp(a) && sexp_isymbolp(b)) { - res = strcmp(sexp_symbol_data(a), + res = strcmp(sexp_lsymbol_data(a), sexp_string_data(sexp_write_to_string(ctx, b))); #endif } else { @@ -101,7 +101,7 @@ static int sexp_object_compare (sexp ctx, sexp a, sexp b) { #if SEXP_USE_HUFF_SYMS if (sexp_isymbolp(a) && sexp_lsymbolp(b)) res = strcmp(sexp_string_data(sexp_write_to_string(ctx, a)), - sexp_symbol_data(b)); + sexp_lsymbol_data(b)); else #endif res = -1; diff --git a/sexp.c b/sexp.c index 7d4a38b8..fd3afaf2 100644 --- a/sexp.c +++ b/sexp.c @@ -1058,8 +1058,8 @@ sexp sexp_intern(sexp ctx, const char *str, sexp_sint_t len) { bucket = (sexp_string_hash(p, len-i, res) % SEXP_SYMBOL_TABLE_SIZE); #endif for (ls=sexp_context_symbols(ctx)[bucket]; sexp_pairp(ls); ls=sexp_cdr(ls)) - if ((sexp_symbol_length(tmp=sexp_car(ls)) == len) - && ! strncmp(str, sexp_symbol_data(tmp), len)) + if ((sexp_lsymbol_length(tmp=sexp_car(ls)) == len) + && ! strncmp(str, sexp_lsymbol_data(tmp), len)) return sexp_car(ls); /* not found, make a new symbol */ @@ -1565,12 +1565,12 @@ sexp sexp_write_one (sexp ctx, sexp obj, sexp out) { sexp_write_char(ctx, '"', out); break; case SEXP_SYMBOL: - str = sexp_symbol_data(obj); - c = sexp_symbol_length(obj) > 0 ? EOF : '|'; - for (i=sexp_symbol_length(obj)-1; i>=0; i--) + str = sexp_lsymbol_data(obj); + c = sexp_lsymbol_length(obj) > 0 ? EOF : '|'; + for (i=sexp_lsymbol_length(obj)-1; i>=0; i--) if (str[i] <= ' ' || str[i] == '\\' || is_separator(str[i])) c = '|'; if (c!=EOF) sexp_write_char(ctx, c, out); - for (i=sexp_symbol_length(obj); i>0; str++, i--) { + for (i=sexp_lsymbol_length(obj); i>0; str++, i--) { if (str[0] == '\\') sexp_write_char(ctx, '\\', out); sexp_write_char(ctx, str[0], out); } @@ -2663,7 +2663,7 @@ sexp sexp_symbol_to_string_op (sexp ctx, sexp self, sexp_sint_t n, sexp sym) { if (sexp_isymbolp(sym)) return sexp_write_to_string(ctx, sym); #endif sexp_assert_type(ctx, sexp_lsymbolp, SEXP_SYMBOL, sym); - return sexp_c_string(ctx, sexp_symbol_data(sym), sexp_symbol_length(sym)); + return sexp_c_string(ctx, sexp_lsymbol_data(sym), sexp_lsymbol_length(sym)); } void sexp_init (void) {