ffi/unsafe: fix make-sized-byte-string on a #f argument

In particular, a #f argument can make sense if the length is 0.
Technically, a byte string's byte array is supposed to be nul-terminated,
but many uses of byte strings get away without that terminator. I've
adjust the documentation to note that `bytes-copy` will work with a
non-terminated byte string.

Merge to v6.1.1
This commit is contained in:
Matthew Flatt 2014-10-14 05:59:35 -06:00
parent da98d60f99
commit 1cc86d3cea
4 changed files with 21 additions and 10 deletions

View File

@ -389,6 +389,12 @@ Returns a byte string made of the given pointer and the given length.
No copying is done. This can be used as an alternative to make
pointer values accessible in Racket when the size is known.
Beware that the representation of a Racket byte string normally
requires a nul terminator at the end of the byte string (after
@racket[length] bytes), but some function work with a byte-string
representation that has no such terminator---notably
@racket[bytes-copy].
If @racket[cptr] is an offset pointer created by @racket[ptr-add], the
offset is immediately added to the pointer. Thus, this function cannot
be used with @racket[ptr-add] to create a substring of a Racket byte

View File

@ -15,6 +15,8 @@
(test #f malloc 0 _int)
(test #f malloc _int 0)
(test 0 bytes-length (make-sized-byte-string #f 0))
;; Check integer-range checking:
(let ()
(define (try-int-boundary N _int _uint)

View File

@ -3178,9 +3178,7 @@ static Scheme_Object *foreign_make_sized_byte_string(int argc, Scheme_Object *ar
scheme_wrong_contract(MYNAME, "cpointer?", 0, argc, argv);
if (!scheme_get_int_val(argv[1],&len))
wrong_intptr(MYNAME, 1, argc, argv);
if (SCHEME_FALSEP(cp)) return scheme_false;
else return
scheme_make_sized_byte_string(SCHEME_FFIANYPTR_OFFSETVAL(cp),
return scheme_make_sized_byte_string(SCHEME_FFIANYPTR_OFFSETVAL(cp),
len, 0);
}
#undef MYNAME
@ -3304,9 +3302,9 @@ static void ffi_call_in_orig_place(ffi_cif *cif, void *c_func, intptr_t cfoff,
/* Done */
mzrt_mutex_unlock(orig_place_mutex);
if (!cached_orig_place_todo)
cached_orig_place_todo = todo;
cached_orig_place_todo = todo;
else
free(todo);
free(todo);
break;
} else {
/* Pause to allow actions such as a master GC.... */

View File

@ -2346,9 +2346,7 @@ static Scheme_Object *do_memop(const char *who, int mode,
scheme_wrong_contract(MYNAME, "cpointer?", 0, argc, argv);
if (!scheme_get_int_val(argv[1],&len))
wrong_intptr(MYNAME, 1, argc, argv);
if (SCHEME_FALSEP(cp)) return scheme_false;
else return
scheme_make_sized_byte_string(SCHEME_FFIANYPTR_OFFSETVAL(cp),
return scheme_make_sized_byte_string(SCHEME_FFIANYPTR_OFFSETVAL(cp),
len, 0);
}
@ -2415,7 +2413,11 @@ static void ffi_call_in_orig_place(ffi_cif *cif, void *c_func, intptr_t cfoff,
void *sh;
int ready;
todo = (FFI_Orig_Place_Call *)malloc(sizeof(FFI_Orig_Place_Call));
if (cached_orig_place_todo) {
todo = cached_orig_place_todo;
cached_orig_place_todo = NULL;
} else
todo = (FFI_Orig_Place_Call *)malloc(sizeof(FFI_Orig_Place_Call));
sh = scheme_get_signal_handle();
todo->signal_handle = sh;
todo->needs_queue = 1;
@ -2466,7 +2468,10 @@ static void ffi_call_in_orig_place(ffi_cif *cif, void *c_func, intptr_t cfoff,
if (!todo->signal_handle) {
/* Done */
mzrt_mutex_unlock(orig_place_mutex);
free(todo);
if (!cached_orig_place_todo)
cached_orig_place_todo = todo;
else
free(todo);
break;
} else {
/* Pause to allow actions such as a master GC.... */