diff --git a/pkgs/racket-pkgs/racket-doc/scribblings/foreign/pointers.scrbl b/pkgs/racket-pkgs/racket-doc/scribblings/foreign/pointers.scrbl index ba680ff9e0..79ac838cb7 100644 --- a/pkgs/racket-pkgs/racket-doc/scribblings/foreign/pointers.scrbl +++ b/pkgs/racket-pkgs/racket-doc/scribblings/foreign/pointers.scrbl @@ -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 diff --git a/pkgs/racket-pkgs/racket-test/tests/racket/foreign-test.rktl b/pkgs/racket-pkgs/racket-test/tests/racket/foreign-test.rktl index bb925aeabf..b2392d64b8 100644 --- a/pkgs/racket-pkgs/racket-test/tests/racket/foreign-test.rktl +++ b/pkgs/racket-pkgs/racket-test/tests/racket/foreign-test.rktl @@ -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) diff --git a/racket/src/foreign/foreign.c b/racket/src/foreign/foreign.c index 14cfca29c7..b5be78debf 100644 --- a/racket/src/foreign/foreign.c +++ b/racket/src/foreign/foreign.c @@ -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.... */ diff --git a/racket/src/foreign/foreign.rktc b/racket/src/foreign/foreign.rktc index 5b6f16c03f..f1ded27583 100755 --- a/racket/src/foreign/foreign.rktc +++ b/racket/src/foreign/foreign.rktc @@ -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.... */