compiler/blob: make blob_reserve_bytes() more useful
authorConnor Abbott <cwabbott0@gmail.com>
Fri, 15 Sep 2017 04:29:46 +0000 (00:29 -0400)
committerJason Ekstrand <jason.ekstrand@intel.com>
Fri, 13 Oct 2017 04:47:06 +0000 (21:47 -0700)
Despite the name, it could only be used if you immediately wrote to the
pointer. Noboby was using it outside of one test, so clearly this
behavior wasn't that useful. Instead, make it return an offset into the
data buffer so that the result isn't invalidated if you later write to
the blob. In conjunction with blob_overwrite_bytes(), this will be
useful for leaving a placeholder and then filling it in later, which
we'll need to do for handling phi nodes when serializing NIR.

v2 (Jason Ekstrand):
 - Detect overflow in the offset + to_write computation

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
src/compiler/blob.c
src/compiler/blob.h
src/compiler/glsl/tests/blob_test.c

index f3ff5d6862e3d2a75ccdda15a7296c8efb1f74b0..65c450ee97923dc14492d4436fef01e23033386d 100644 (file)
@@ -132,7 +132,7 @@ blob_overwrite_bytes(struct blob *blob,
                      size_t to_write)
 {
    /* Detect an attempt to overwrite data out of bounds. */
-   if (blob->size < offset + to_write)
+   if (offset + to_write < offset || blob->size < offset + to_write)
       return false;
 
    VG(VALGRIND_CHECK_MEM_IS_DEFINED(bytes, to_write));
@@ -158,15 +158,15 @@ blob_write_bytes(struct blob *blob, const void *bytes, size_t to_write)
    return true;
 }
 
-uint8_t *
+ssize_t
 blob_reserve_bytes(struct blob *blob, size_t to_write)
 {
-   uint8_t *ret;
+   ssize_t ret;
 
    if (! grow_to_fit (blob, to_write))
-      return NULL;
+      return -1;
 
-   ret = blob->data + blob->size;
+   ret = blob->size;
    blob->size += to_write;
 
    return ret;
index ec80b78284cea610445ad005b0aeec3eaa99681d..72a601d5345678a0b70fc683cfc44256aedce18e 100644 (file)
@@ -129,21 +129,13 @@ blob_write_bytes(struct blob *blob, const void *bytes, size_t to_write);
  * Reserve space in \blob for a number of bytes.
  *
  * Space will be allocated within the blob for these byes, but the bytes will
- * be left uninitialized. The caller is expected to use the return value to
- * write directly (and immediately) to these bytes.
+ * be left uninitialized. The caller is expected to use \sa
+ * blob_overwrite_bytes to write to these bytes.
  *
- * \note The return value is valid immediately upon return, but can be
- * invalidated by any other call to a blob function. So the caller should call
- * blob_reserve_byes immediately before writing through the returned pointer.
- *
- * This function is intended to be used when interfacing with an existing API
- * that is not aware of the blob API, (so that blob_write_bytes cannot be
- * called).
- *
- * \return A pointer to space allocated within \blob to which \to_write bytes
- * can be written, (or NULL in case of any allocation error).
+ * \return An offset to space allocated within \blob to which \to_write bytes
+ * can be written, (or -1 in case of any allocation error).
  */
-uint8_t *
+ssize_t
 blob_reserve_bytes(struct blob *blob, size_t to_write);
 
 /**
index d49f4a02cf9a18ecdb5583c0abf2eacadb8c4e27..0b4955b6b689313a41013721d2e7c788ba70a2b4 100644 (file)
@@ -120,7 +120,7 @@ test_write_and_read_functions (void)
 {
    struct blob blob;
    struct blob_reader reader;
-   uint8_t *reserved;
+   ssize_t reserved;
    size_t str_offset, uint_offset;
    uint8_t reserve_buf[sizeof(reserve_test_str)];
 
@@ -131,7 +131,7 @@ test_write_and_read_functions (void)
    blob_write_bytes(&blob, bytes_test_str, sizeof(bytes_test_str));
 
    reserved = blob_reserve_bytes(&blob, sizeof(reserve_test_str));
-   memcpy(reserved, reserve_test_str, sizeof(reserve_test_str));
+   blob_overwrite_bytes(&blob, reserved, reserve_test_str, sizeof(reserve_test_str));
 
    /* Write a placeholder, (to be replaced later via overwrite_bytes) */
    str_offset = blob.size;