summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/blob.c16
-rw-r--r--src/compiler/blob.h22
2 files changed, 37 insertions, 1 deletions
diff --git a/src/compiler/blob.c b/src/compiler/blob.c
index 2e20a11dc0c..a78fcd41a76 100644
--- a/src/compiler/blob.c
+++ b/src/compiler/blob.c
@@ -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
@@ -105,6 +110,17 @@ blob_init(struct blob *blob)
blob->data = NULL;
blob->allocated = 0;
blob->size = 0;
+ blob->fixed_allocation = false;
+ blob->out_of_memory = false;
+}
+
+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;
}
diff --git a/src/compiler/blob.h b/src/compiler/blob.h
index 8a7a28b4f3c..e23e392eedd 100644
--- a/src/compiler/blob.h
+++ b/src/compiler/blob.h
@@ -56,6 +56,12 @@ struct blob {
/** The number of bytes that have actual data written to them. */
size_t size;
+ /** True if \c data a fixed allocation that we cannot resize
+ *
+ * \see blob_init_fixed
+ */
+ bool fixed_allocation;
+
/**
* True if we've ever failed to realloc or if we go pas the end of a fixed
* allocation blob.
@@ -85,12 +91,26 @@ void
blob_init(struct blob *blob);
/**
+ * Init a new, fixed-size blob.
+ *
+ * A fixed-size blob has a fixed block of data that will not be freed on
+ * blob_finish and will never be grown. If we hit the end, we simply start
+ * returning false from the write functions.
+ */
+void
+blob_init_fixed(struct blob *blob, void *data, size_t size);
+
+/**
* Finish a blob and free its memory.
+ *
+ * If \blob was initialized with blob_init_fixed, the data pointer is
+ * considered to be owned by the user and will not be freed.
*/
static inline void
blob_finish(struct blob *blob)
{
- free(blob->data);
+ if (!blob->fixed_allocation)
+ free(blob->data);
}
/**