glsl_parser_extra: Add utility to copy symbols between symbol tables
[mesa.git] / src / compiler / blob.c
index 65e1376e160f04c6786937223439cfe79467e758..8dd254fefc6dfe0899280af1b13a4006fbbe1df8 100644 (file)
@@ -52,6 +52,11 @@ grow_to_fit(struct blob *blob, size_t additional)
    if (blob->size + additional <= blob->allocated)
       return true;
 
+   if (blob->fixed_allocation) {
+      blob->out_of_memory = true;
+      return false;
+   }
+
    if (blob->allocated == 0)
       to_allocate = BLOB_INITIAL_SIZE;
    else
@@ -86,7 +91,8 @@ align_blob(struct blob *blob, size_t alignment)
       if (!grow_to_fit(blob, new_size - blob->size))
          return false;
 
-      memset(blob->data + blob->size, 0, new_size - blob->size);
+      if (blob->data)
+         memset(blob->data + blob->size, 0, new_size - blob->size);
       blob->size = new_size;
    }
 
@@ -99,19 +105,24 @@ align_blob_reader(struct blob_reader *blob, size_t alignment)
    blob->current = blob->data + ALIGN(blob->current - blob->data, alignment);
 }
 
-struct blob *
-blob_create()
+void
+blob_init(struct blob *blob)
 {
-   struct blob *blob = (struct blob *) malloc(sizeof(struct blob));
-   if (blob == NULL)
-      return NULL;
-
    blob->data = NULL;
    blob->allocated = 0;
    blob->size = 0;
+   blob->fixed_allocation = false;
    blob->out_of_memory = false;
+}
 
-   return blob;
+void
+blob_init_fixed(struct blob *blob, void *data, size_t size)
+{
+   blob->data = data;
+   blob->allocated = size;
+   blob->size = 0;
+   blob->fixed_allocation = true;
+   blob->out_of_memory = false;
 }
 
 bool
@@ -121,12 +132,13 @@ 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));
 
-   memcpy(blob->data + offset, bytes, to_write);
+   if (blob->data)
+      memcpy(blob->data + offset, bytes, to_write);
 
    return true;
 }
@@ -139,26 +151,41 @@ blob_write_bytes(struct blob *blob, const void *bytes, size_t to_write)
 
    VG(VALGRIND_CHECK_MEM_IS_DEFINED(bytes, to_write));
 
-   memcpy(blob->data + blob->size, bytes, to_write);
+   if (blob->data)
+      memcpy(blob->data + blob->size, bytes, to_write);
    blob->size += to_write;
 
    return true;
 }
 
-uint8_t *
+intptr_t
 blob_reserve_bytes(struct blob *blob, size_t to_write)
 {
-   uint8_t *ret;
+   intptr_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;
 }
 
+intptr_t
+blob_reserve_uint32(struct blob *blob)
+{
+   align_blob(blob, sizeof(uint32_t));
+   return blob_reserve_bytes(blob, sizeof(uint32_t));
+}
+
+intptr_t
+blob_reserve_intptr(struct blob *blob)
+{
+   align_blob(blob, sizeof(intptr_t));
+   return blob_reserve_bytes(blob, sizeof(intptr_t));
+}
+
 bool
 blob_write_uint32(struct blob *blob, uint32_t value)
 {
@@ -167,11 +194,15 @@ blob_write_uint32(struct blob *blob, uint32_t value)
    return blob_write_bytes(blob, &value, sizeof(value));
 }
 
+#define ASSERT_ALIGNED(_offset, _align) \
+   assert(ALIGN((_offset), (_align)) == (_offset))
+
 bool
 blob_overwrite_uint32 (struct blob *blob,
                        size_t offset,
                        uint32_t value)
 {
+   ASSERT_ALIGNED(offset, sizeof(value));
    return blob_overwrite_bytes(blob, offset, &value, sizeof(value));
 }
 
@@ -191,6 +222,15 @@ blob_write_intptr(struct blob *blob, intptr_t value)
    return blob_write_bytes(blob, &value, sizeof(value));
 }
 
+bool
+blob_overwrite_intptr (struct blob *blob,
+                       size_t offset,
+                       intptr_t value)
+{
+   ASSERT_ALIGNED(offset, sizeof(value));
+   return blob_overwrite_bytes(blob, offset, &value, sizeof(value));
+}
+
 bool
 blob_write_string(struct blob *blob, const char *str)
 {
@@ -198,10 +238,10 @@ blob_write_string(struct blob *blob, const char *str)
 }
 
 void
-blob_reader_init(struct blob_reader *blob, uint8_t *data, size_t size)
+blob_reader_init(struct blob_reader *blob, const void *data, size_t size)
 {
    blob->data = data;
-   blob->end = data + size;
+   blob->end = blob->data + size;
    blob->current = data;
    blob->overrun = false;
 }
@@ -224,10 +264,10 @@ ensure_can_read(struct blob_reader *blob, size_t size)
    return false;
 }
 
-void *
+const void *
 blob_read_bytes(struct blob_reader *blob, size_t size)
 {
-   void *ret;
+   const void *ret;
 
    if (! ensure_can_read (blob, size))
       return NULL;
@@ -240,9 +280,9 @@ blob_read_bytes(struct blob_reader *blob, size_t size)
 }
 
 void
-blob_copy_bytes(struct blob_reader *blob, uint8_t *dest, size_t size)
+blob_copy_bytes(struct blob_reader *blob, void *dest, size_t size)
 {
-   uint8_t *bytes;
+   const void *bytes;
 
    bytes = blob_read_bytes(blob, size);
    if (bytes == NULL)