aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ast.h1
-rw-r--r--include/buffer.h8
-rw-r--r--include/scoped_allocator.h8
-rw-r--r--src/ast.c2
-rw-r--r--src/buffer.c42
-rw-r--r--src/parser.c2
-rw-r--r--src/scoped_allocator.c19
7 files changed, 59 insertions, 23 deletions
diff --git a/include/ast.h b/include/ast.h
index ef06257..f3580c0 100644
--- a/include/ast.h
+++ b/include/ast.h
@@ -4,6 +4,7 @@
#include "buffer_view.h"
#include "buffer.h"
#include "misc.h"
+#include "scoped_allocator.h"
typedef struct FunctionDecl FunctionDecl;
typedef struct FunctionCall FunctionCall;
diff --git a/include/buffer.h b/include/buffer.h
index 700ae7b..e0c4046 100644
--- a/include/buffer.h
+++ b/include/buffer.h
@@ -1,19 +1,21 @@
#ifndef AMALGAM_BUFFER_H
#define AMALGAM_BUFFER_H
-#include "scoped_allocator.h"
+#include "types.h"
+#include "misc.h"
#define BUFFER_OK 0
#define BUFFER_ALLOC_FAIL -1
typedef struct {
- ScopedAllocator *allocator;
+ struct ScopedAllocator *allocator;
char* data;
usize size;
usize capacity;
} Buffer;
-CHECK_RESULT int buffer_init(Buffer *self, ScopedAllocator *allocator, usize initial_capacity);
+CHECK_RESULT int buffer_init(Buffer *self, struct ScopedAllocator *allocator);
+void buffer_deinit(Buffer *self);
CHECK_RESULT int buffer_append(Buffer *self, void *data, usize size);
void* buffer_get(Buffer *self, usize index, usize type_size);
diff --git a/include/scoped_allocator.h b/include/scoped_allocator.h
index 1193439..fdaee2a 100644
--- a/include/scoped_allocator.h
+++ b/include/scoped_allocator.h
@@ -3,8 +3,10 @@
#include "misc.h"
#include "types.h"
+#include "buffer.h"
typedef struct ScopedAllocatorNode ScopedAllocatorNode;
+typedef struct ScopedAllocator ScopedAllocator;
struct ScopedAllocatorNode {
char *data;
@@ -12,10 +14,11 @@ struct ScopedAllocatorNode {
ScopedAllocatorNode *next;
};
-typedef struct {
+struct ScopedAllocator {
ScopedAllocatorNode head;
ScopedAllocatorNode *current;
-} ScopedAllocator;
+ Buffer buffers;
+};
CHECK_RESULT int scoped_allocator_node_init(ScopedAllocatorNode *self);
void scoped_allocator_node_deinit(ScopedAllocatorNode *self);
@@ -23,5 +26,6 @@ void scoped_allocator_node_deinit(ScopedAllocatorNode *self);
CHECK_RESULT int scoped_allocator_init(ScopedAllocator *self);
void scoped_allocator_deinit(ScopedAllocator *self);
CHECK_RESULT int scoped_allocator_alloc(ScopedAllocator *self, usize size, void **mem);
+CHECK_RESULT int scoped_allocator_add_buffer(ScopedAllocator *self, Buffer *buffer);
#endif \ No newline at end of file
diff --git a/src/ast.c b/src/ast.c
index 2802c3b..3ea4fe1 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -9,7 +9,7 @@ Ast ast_none() {
int funcdecl_init(FunctionDecl *self, ScopedAllocator *allocator) {
self->name = create_buffer_view_null();
- return buffer_init(&self->body, allocator, sizeof(Ast) * 4);
+ return buffer_init(&self->body, allocator);
}
int funcdecl_add_to_body(FunctionDecl *self, Ast ast) {
diff --git a/src/buffer.c b/src/buffer.c
index ad50771..349c186 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1,41 +1,55 @@
#include "../include/buffer.h"
#include "../include/alloc.h"
#include "../include/mem.h"
+#include "../include/scoped_allocator.h"
#include <assert.h>
-int buffer_init(Buffer *self, ScopedAllocator *allocator, usize initial_capacity) {
+int buffer_init(Buffer *self, ScopedAllocator *allocator) {
+ self->data = NULL;
+ self->size = 0;
+ self->capacity = 0;
self->allocator = allocator;
+ if(self->allocator)
+ return scoped_allocator_add_buffer(self->allocator, self);
+ return 0;
+}
+
+void buffer_deinit(Buffer *self) {
+ am_free(self->data);
+ self->data = NULL;
self->size = 0;
- self->capacity = initial_capacity;
- return scoped_allocator_alloc(self->allocator, initial_capacity, (void**)&self->data);
+ self->capacity = 0;
}
-static CHECK_RESULT int buffer_ensure_capacity_for(Buffer *self, usize size) {
+static CHECK_RESULT int buffer_ensure_capacity(Buffer *self, usize new_capacity) {
+ usize capacity;
void *new_mem;
int alloc_result;
- usize new_capacity;
- new_capacity = self->size + size;
if(self->capacity >= new_capacity)
return BUFFER_OK;
- /*
- We are using alloc here instead of realloc because we are using scoped allocator
- which doesn't reallocate. TODO: Verify if scoped allocator node size is enough to hold buffers...
- */
- alloc_result = scoped_allocator_alloc(self->allocator, new_capacity, &new_mem);
+ capacity = self->capacity;
+ if(capacity == 0) {
+ capacity = new_capacity;
+ } else {
+ while(capacity < new_capacity) {
+ capacity *= 1.5;
+ }
+ }
+
+ alloc_result = am_realloc(self->data, capacity, &new_mem);
if(alloc_result != ALLOC_OK)
return BUFFER_ALLOC_FAIL;
self->data = new_mem;
- self->capacity = new_capacity;
+ self->capacity = capacity;
return BUFFER_OK;
}
int buffer_append(Buffer *self, void *data, usize size) {
- return_if_error(buffer_ensure_capacity_for(self, size));
+ return_if_error(buffer_ensure_capacity(self, self->size + size));
am_memcpy(self->data + self->size, data, size);
- self->size += size;
return BUFFER_OK;
}
diff --git a/src/parser.c b/src/parser.c
index 6a1c796..78b0018 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -8,7 +8,7 @@ static CHECK_RESULT int parser_parse_body(Parser *self, Ast *ast);
int parser_init(Parser *self) {
return_if_error(scoped_allocator_init(&self->allocator));
- return_if_error(buffer_init(&self->ast_objects, &self->allocator, sizeof(Ast) * 8));
+ return_if_error(buffer_init(&self->ast_objects, &self->allocator));
return PARSER_OK;
}
diff --git a/src/scoped_allocator.c b/src/scoped_allocator.c
index cbf1aad..7e2cb0d 100644
--- a/src/scoped_allocator.c
+++ b/src/scoped_allocator.c
@@ -2,7 +2,7 @@
#include "../include/alloc.h"
#include <assert.h>
-#define ALLOC_NODE_SIZE 65536
+#define ALLOC_NODE_SIZE 4096
int scoped_allocator_node_init(ScopedAllocatorNode *self) {
self->data = NULL;
@@ -25,11 +25,22 @@ void scoped_allocator_node_deinit(ScopedAllocatorNode *self) {
int scoped_allocator_init(ScopedAllocator *self) {
return_if_error(scoped_allocator_node_init(&self->head));
self->current = &self->head;
- return 0;
+ return buffer_init(&self->buffers, NULL);
}
+
void scoped_allocator_deinit(ScopedAllocator *self) {
+ Buffer *buffer;
+ Buffer *buffer_end;
+
scoped_allocator_node_deinit(&self->head);
self->current = NULL;
+ buffer = (Buffer*)&self->buffers.data[0];
+ buffer_end = buffer + self->buffers.size / sizeof(Buffer);
+ while(buffer != buffer_end) {
+ buffer_deinit(buffer);
+ ++buffer;
+ }
+ buffer_deinit(&self->buffers);
}
static CHECK_RESULT int scoped_allocator_ensure_capacity_for(ScopedAllocator *self, usize size) {
@@ -57,4 +68,8 @@ int scoped_allocator_alloc(ScopedAllocator *self, usize size, void **mem) {
*mem = &self->current->data[self->current->size];
self->current->size += size;
return 0;
+}
+
+int scoped_allocator_add_buffer(ScopedAllocator *self, Buffer *buffer) {
+ return buffer_append(&self->buffers, buffer, sizeof(buffer));
} \ No newline at end of file